在对象数组中选择唯一项

时间:2019-06-03 05:54:24

标签: javascript unique

假设我有以下对象数组

[{a:1,b:2,c:4}, {a:3,b:4,c:7}, {a:7,b:10,c:10}, {a:1, b:2,c:4}]

如何选择此数组中的唯一项。我需要比较两个字段(仅a,b,不包括c),我所看到的示例显示的地图仅包含一个字段。

3 个答案:

答案 0 :(得分:1)

您可以使用嵌套过滤器,并检查具有相同ab的匹配元素的数量为1:

const input = [{a:1,b:2,c:4}, {a:3,b:4,c:7}, {a:7,b:10,c:10}, {a:1, b:2,c:4}];
const output = input.filter(
  ({ a, b }) => input.filter(obj => obj.a === a && obj.b === b).length === 1
);
console.log(output);

对于O(N)复杂度,可以简化为用num_num索引的对象或类似的对象,然后仅选择其中包含一项的值:

const input = [{a:1,b:2,c:4}, {a:3,b:4,c:7}, {a:7,b:10,c:10}, {a:1, b:2,c:4}];
const inputByAB = input.reduce((accum, obj) => {
  const key = `${obj.a}_${obj.b}`;
  if (!accum[key]) {
    accum[key] = [];
  }
  accum[key].push(obj);
  return accum;
}, {});
const output = Object.values(inputByAB)
  .filter(arr => arr.length === 1)
  .flat();
console.log(output);

如果您不能使用.flat,请改为传播concat:

const input = [{a:1,b:2,c:4}, {a:3,b:4,c:7}, {a:7,b:10,c:10}, {a:1, b:2,c:4}];
const inputByAB = input.reduce((accum, obj) => {
  const key = `${obj.a}_${obj.b}`;
  if (!accum[key]) {
    accum[key] = [];
  }
  accum[key].push(obj);
  return accum;
}, {});
const output = [].concat(...
  Object.values(inputByAB)
    .filter(arr => arr.length === 1)
);
console.log(output);

答案 1 :(得分:1)

对于动态键,请创建一个函数,该函数将代表键的数组和数组字符串作为输入。

创建另一个帮助程序方法,该方法比较两个对象的给定键。

在对象数组上使用filter(),然后在给定键的当前索引不等于当前对象之前使用every()元素。

let arr = [{a:1,b:2,c:4}, {a:3,b:4,c:7}, {a:7,b:10,c:10}, {a:1, b:2,c:4}];
function comp(obj1,obj2,keys){
  return keys.every(k => obj1[k] === obj2[k]);
}
function getUnique(arr,keys){
  return arr.filter((x,i) => arr.slice(0,i).every(a => !comp(a,x,keys)))
}

console.log(getUnique(arr,['a','b']))

答案 2 :(得分:0)

您可以reduceMap作为阵列的数组。将ab属性的组合用作键,以便删除重复项。然后使用Map#values获取输出

const input = [{a:1,b:2,c:4}, {a:3,b:4,c:7}, {a:7,b:10,c:10}, {a:1, b:2,c:4}],
      mapped = input.reduce((map, o) => map.set(o.a + "_" + o.b, o), new Map),
      output = Array.from(mapped.values());

console.log(output)