0

I would like to insert an object into a sorted array of objects, but to know at which position to insert it :)

I have the following array of objects, the array is sorted by IP field:

let array = [{ 'ip': '192.168.0.1' }, { 'ip': '192.168.0.4'}, { 'ip': '192.168.0.10'}, { 'ip': '192.168.0.50'}, { 'ip': '192.168.0.60'}, ]; 

Now I would like to insert a new object to the array:

const newObject = { ip: '192.168.0.13' };

How can I add this new object to the correct position?

So that my array then looks like:

 let array = [{ 'ip': '192.168.0.1' }, { 'ip': '192.168.0.4'}, { 'ip': '192.168.0.10'}, { ip: '192.168.0.13' }, { 'ip': '192.168.0.50'}, { 'ip': '192.168.0.60'}, ]; 

How could I find the correct index, where to insert the item ?

4 Answers 4

1

Another answer using findIndex and splice but with a different way to compare the IP-addresses.

By converting them into a single 32bit number. imo. simpler to deal with than an array of 4 bytes.

let array = [
  { 'ip': '192.168.0.1'}, 
  { 'ip': '192.168.0.4'}, 
  { 'ip': '192.168.0.10'}, 
  { 'ip': '192.168.0.50'},
  { 'ip': '192.168.0.60'},
]; 

const newObject = { ip: '192.168.0.13' };

const foldIp = (a,b) => a<<8 | b;
const ipValue = item => item.ip.split(".").reduce(foldIp, 0);

const newObjectValue = ipValue(newObject);
const index = array.findIndex(item => ipValue(item) > newObjectValue);

if (index === -1) {
  array.push(newObject);
} else {
  array.splice(index, 0, newObject);
}

console.log(array);

// or use it to sort();
console.log(
  "sort descending:", // as the array is currently sorted ascending
  array.sort((a,b) => ipValue(b) - ipValue(a))
);
.as-console-wrapper{top:0;max-height:100%!important}

Added both conversions

const IP = {
  // 3232235521 -> '192.168.0.1'
  toString(value) {
    return `${value >>> 24}.${value >> 16 & 0xFF}.${value >> 8 & 0xFF}.${value & 0xFF}`
  },
  // '192.168.0.1' -> 3232235521
  toUint(value) {
    const arr = value.split(".");
    return (arr[0] << 24 | arr[1] << 16 | arr[2] << 8 | arr[3]) >>> 0;
  }
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can try this

array.push(newObject);

And after that sort it again.

Comments

1

Using Array.findIndex, you can find the position to be inserted into the current array and using Array.splice, you can insert ip address to that position.

let array = [{ 'ip': '192.168.0.1' }, { 'ip': '192.168.0.4'}, { 'ip': '192.168.0.10'}, { 'ip': '192.168.0.50'}, { 'ip': '192.168.0.60'}, ]; 
const newObject = { ip: '192.168.0.13' };

const newIpArr = newObject.ip.split(".").map(item => parseInt(item));
const insertPos = array.findIndex(({ ip }) => {
  const ipArr = ip.split(".").map(item => parseInt(item));
  for (let index = 0; index < ipArr.length; index ++) {
    if (ipArr[index] > newIpArr[index]) {
      return true;
    }
  }
  return false;
});
array.splice(insertPos, 1, newObject);
console.log(array);

Comments

1

You can use splice and set the delete count to 0 to add at a specific position but this would mutate the original array.

The same can be done with slice and spread operator but it would not mutate the original array.

To find the exact position where you need to insert, you can pass a predicate to the findIndex function. The findIndex function would the right index where you need to insert the new object.

The predicate here would be an IP comparison function. In my example I made a crude IP comparing function which does the job:

let array = [{ 'ip': '192.168.0.1' }, { 'ip': '192.168.0.4'}, { 'ip': '192.168.0.10'}, { 'ip': '192.168.0.50'}, { 'ip': '192.168.0.60'}, ]; 
const newObject = { ip: '192.168.0.13' };

const compareIp = (ip1, ip2) => {
  const arr1 = ip1.split(".").map(n => +n);
  const arr2 = ip2.split(".").map(n => +n);
  return arr1.every((e, i) => e <= arr2[i]);
}

//Not mutating original array
const insertAtPosition = (arr, obj) => {
  const idx = arr.findIndex(o =>  compareIp(obj.ip, o.ip));
  return [...array.slice(0, idx), obj,...array.slice(idx)]
}

//Mutating original array
const insertAtPositionMutated = (arr, obj) => {
   const idx = arr.findIndex(o =>  compareIp(obj.ip, o.ip));
  arr.splice(idx, 0, obj);
  return arr
}

console.log(insertAtPosition(array, newObject));

console.log(insertAtPositionMutated(array, newObject));

1 Comment

I know about that, but what if I have a bigger list, I would want to find at which position to insert item ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.