简体   繁体   English

Javascript 将项目插入 object 数组中的正确 position

[英]Javascript insert item into correct position in array of object

I would like to insert an object into a sorted array of objects, but to know at which position to insert it:)我想将 object 插入到已排序的对象数组中,但要知道在哪个 position 中插入它:)

I have the following array of objects, the array is sorted by IP field:我有以下对象数组,该数组按 IP 字段排序:

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:现在我想向数组中插入一个新的 object:

const newObject = { ip: '192.168.0.13' };

How can I add this new object to the correct position?如何将这个新的 object 添加到正确的 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?我怎样才能找到正确的索引,在哪里插入项目?

You can use splice and set the delete count to 0 to add at a specific position but this would mutate the original array.您可以使用splice并将删除计数设置为0以在特定的position处添加,但这会改变原始数组。

The same can be done with slice and spread operator but it would not mutate the original array. slice和展开运算符也可以这样做,但它不会改变原始数组。

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.要找到您需要插入的确切 position,您可以将谓词传递给findIndex findIndex function 将是您需要插入新 object 的正确索引。

The predicate here would be an IP comparison function. In my example I made a crude IP comparing function which does the job:这里的谓词是 IP 比较 function。在我的示例中,我做了一个粗略的 IP 比较 function 来完成这项工作:

 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));

You can try this你可以试试这个

array.push(newObject);

And after that sort it again.然后再排序。

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.使用Array.findIndex ,您可以找到要插入当前数组的 position 并使用Array.splice ,您可以将 ip 地址插入到该 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);

Another answer using findIndex and splice but with a different way to compare the IP-addresses.另一个使用findIndexsplice的答案,但使用不同的方式来比较 IP 地址。

By converting them into a single 32bit number.通过将它们转换为单个 32 位数字。 imo.国际海事组织。 simpler to deal with than an array of 4 bytes.比 4 字节的数组更容易处理。

 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;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM