【问题标题】:Selecting unique items in an array of objects [closed]在对象数组中选择唯一项目[关闭]
【发布时间】:2019-06-03 05:54:24
【问题描述】:

假设我有以下对象数组

[{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),并且我看到的示例显示了一个仅采用单个字段的地图。

【问题讨论】:

标签: javascript unique


【解决方案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);

【讨论】:

    【解决方案2】:

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

    创建另一个帮助方法来比较两个对象的给定键。

    在对象数组上使用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']))

    【讨论】:

      【解决方案3】:

      您可以使用Map 作为累加器的reduce 数组。使用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)

      【讨论】:

      • 谢谢大家的回复,我想我忘了说,我还需要重复项的单项,不要完全忽略它们。上面给出的示例代码完全删除了重复项,我需要它的一个实例。
      • @tmpdev 它不会完全删除重复项。它为每个唯一的 ab 保留一个项目。输出有 3 个项目。输出中只有一个带有a:1,b:2 的项目
      • @tmpdev 如果这回答了您的问题,请投票并将其标记为已接受。
      猜你喜欢
      • 2017-11-03
      • 2018-10-02
      • 1970-01-01
      • 2021-03-03
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多