根据字段的值获取对象的最后一次出现

时间:2019-04-23 21:38:50

标签: javascript node.js json

从类似

的数组中

[{'name': 'a', 'val': 1}, {'name': 'b', 'val': 2}, {'name': 'a', 'val': 3}]

我想去:

[{ name: 'b', val: 2 }, { name: 'a', val: 3 }]

例如,可以通过以下方式实现:

arrOut = _.uniqBy(arrIn.reverse(), 'name').reverse();

但是我正在寻找一种更快/更清洁的方法,而无需两次反转整个数组。

3 个答案:

答案 0 :(得分:2)

这是一个想法:在数组上迭代两次。第一次计算每个名称的出现次数,第二次如果元素的计数不为1,则过滤掉元素。

示例:

const arrIn = [{'name': 'a', 'val': 1}, {'name': 'b', 'val': 2}, {'name': 'a', 'val': 3}];

const counter = Object.create(null);
for (const element of arrIn) {
  counter[element.name] = (counter[element.name] || 0) + 1;
}

const arrOut = arrIn.filter(element => counter[element.name]-- === 1);
console.log(arrOut);

另一种方法是以相反的顺序遍历数组,跟踪您所看到的名称并在结果上调用.reverse

const arrIn = [{'name': 'a', 'val': 1}, {'name': 'b', 'val': 2}, {'name': 'a', 'val': 3}];
const arrOut = [];

const seen = new Set();
for (let i = arrIn.length; i--;) {
  if (!seen.has(arrIn[i].name)) {
    arrOut.push(arrIn[i]);
    seen.add(arrIn[i].name);
  }
}

console.log(arrOut.reverse());

答案 1 :(得分:0)

尝试使用shift()

此方法删除第一个数组元素

答案 2 :(得分:0)

如果应保留原始顺序,一种替代方法是将Array.filter()Array.some()结合使用。这是我尝试保留元素的原始顺序:

let input = [
  {'name': 'a', 'val': 1},
  {'name': 'b', 'val': 2},
  {'name': 'a', 'val': 3}
];

let res = input.filter(
    ({name, val}, idx, arr) => !arr.some((o, j) => o.name === name && j > idx)
);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

或者,可以使用Array.reduceRight()Set来跟踪已经访问过的姓名(如 @Felix Kling 所示) )

let input = [
  {'name': 'a', 'val': 1},
  {'name': 'b', 'val': 2},
  {'name': 'a', 'val': 3},
  {'name': 'b', 'val': 12},
  {'name': 'c', 'val': 7},
  {'name': 'b', 'val': 22}
];

let res = input.reduceRight((acc, obj) =>
{
   if (acc.visited.has(obj.name))
       return acc;

   acc.visited.add(obj.name);
   acc.res.unshift(obj);
   return acc;

}, {res: [], visited: new Set()});

console.log(res.res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}