通过对象属性从对象数组中删除少于元素的元素

时间:2019-01-24 22:01:20

标签: javascript arrays

我有一个对象数组:

[
{
  incoming_number: 1,
  incoming_number_fraction: 0,
  article:'a1'
},
{
  incoming_number: 2,
  incoming_number_fraction: 0,
  article:'a2'
},
{
  incoming_number: 2,
  incoming_number_fraction: 2,
  article:'a3'
},
{
  incoming_number: 3,
  incoming_number_fraction: 0,
  article:'a4'
},
{
  incoming_number: 4,
  incoming_number_fraction: 0,
  article:'a5'
},
{
  incoming_number: 4,
  incoming_number_fraction: 2,
  article:'a6'
},
{
  incoming_number: 4,
  incoming_number_fraction: 4,
  article:'a7'
},
]

任务是通过此逻辑从数组中删除元素:如果存在具有类似“ incoming_number” 的元素,则必须保存具有最大“ incoming_number_fraction” 的元素并删除其他所有
结果应为:

[
{
      incoming_number: 1,
      incoming_number_fraction: 0
},
{
      incoming_number: 2,
      incoming_number_fraction: 2
},
{
      incoming_number: 3,
      incoming_number_fraction: 0
},
{
      incoming_number: 4,
      incoming_number_fraction: 4
},
]  

数组中有很多元素(超过10000个),我想以最少的步数执行此操作。

编辑
我尝试这样的事情:

for (let i = 0; i < arr.length ; i++) {  
if (arr[i]['incoming_number'] === arr[i + 1]['incoming_number']) {
  let j = i + 1
  while (arr[j]['incoming_number'] === arr[j + 1]['incoming_number']) {
    j++
  }
}

arr.splice(i, j-1)
}  

但这不起作用...
编辑2
添加有关数组中对象的更多信息。

2 个答案:

答案 0 :(得分:1)

使用findIndex或grep在大数组中查找所选数字不利于性能。 因此将数字用作属性将是查找对象并更改incoming_number_fraction的最快方法。

使用grep,findindex可能会导致代码更加复杂,但性能却不佳。在这种情况下,您需要的性能要比较小的代码还要多。

看看我的例子,让我知道。

var arr=[
{
  incoming_number: 1,
  incoming_number_fraction: 0,
  article:'a1'
},
{
  incoming_number: 2,
  incoming_number_fraction: 0,
  article:'a2'
},
{
  incoming_number: 2,
  incoming_number_fraction: 2,
  article:'a3'
},
{
  incoming_number: 3,
  incoming_number_fraction: 0,
  article:'a4'
},
{
  incoming_number: 4,
  incoming_number_fraction: 0,
  article:'a5'
},
{
  incoming_number: 4,
  incoming_number_fraction: 2,
  article:'a6'
},
{
  incoming_number: 4,
  incoming_number_fraction: 4,
  article:'a7'
},
]

var finalResult = [];
var result = {};
var includedNumbers = []
arr.forEach(function(item){
var number = item.incoming_number;
if (!result[item.incoming_number]){ // with Index, is the fastest way 
     result[number] = item;
     includedNumbers.push(number);
  }else {
     if (result[number].incoming_number_fraction< item.incoming_number_fraction ){
         result[number] = item;
     }
   
  }
});

// now lets clean the result 
includedNumbers.forEach(function(item){
  finalResult.push(result[item])
});

console.log(finalResult)

答案 1 :(得分:0)

最简单的方法是使用reduce,因为一次迭代即可获得结果,并将逻辑直接应用于结果数组。

const obj = [{
    incoming_number: 1,
    incoming_number_fraction: 0
  },
  {
    incoming_number: 2,
    incoming_number_fraction: 0
  },
  {
    incoming_number: 2,
    incoming_number_fraction: 2
  },
  {
    incoming_number: 3,
    incoming_number_fraction: 0
  },
  {
    incoming_number: 4,
    incoming_number_fraction: 0
  },
  {
    incoming_number: 4,
    incoming_number_fraction: 2
  },
  {
    incoming_number: 4,
    incoming_number_fraction: 4
  },
]

const result = obj.reduce((accum, currentValue) => {
  const index = accum.findIndex(item => currentValue.incoming_number === item.incoming_number);
  //if the index is -1 it means we didn't added that entry, so we just push it.
  if (index === -1) {
    accum.push(currentValue);
  } else {
    //this means that we have an entry with that incoming number, then we compare the incoming_number_fraction
    if (currentValue.incoming_number_fraction > accum[index].incoming_number_fraction) {
      accum[index] = currentValue;
    }
  }
  return accum;
}, [])

console.log(result)