从一组对象中,收集并删除JavaScript中所有属性的重复项

时间:2018-04-09 15:42:19

标签: javascript arrays object

给出一组数据:

[
  { name: 'apple',      color: 'red',    hasPeel: false },
  { name: 'banana',     color: 'yellow', hasPeel: true },
  { name: 'orange',     color: 'orange', hasPeel: true },
  { name: 'strawberry', color: 'red',    hasPeel: false }
]

我想得到一个像这样的对象:

{
  name: ['apple', 'banana', 'orange', 'strawberry'],
  color: ['red', 'yellow', 'orange'],
  hasPeel: [true, false]
}

(按属性分组,删除重复项)

实现这一目标的最有效方法是什么?

我一直在玩不同的ES6技巧和lodash助手,但还没有找到一种只能迭代一次数组的有效方法。

4 个答案:

答案 0 :(得分:4)

您可以使用reduce()forEach()方法构建对象,并使用ES6 Set从数组中删除重复值。



const data = [{"name":"apple","color":"red","hasPeel":false},{"name":"banana","color":"yellow","hasPeel":true},{"name":"orange","color":"orange","hasPeel":true},{"name":"strawberry","color":"red","hasPeel":false}]

const result = data.reduce((r, e) => {
  Object.keys(e).forEach(k => {
    if (!r[k]) r[k] = [e[k]]
    else r[k] = [...new Set(r[k]).add(e[k])]
  });
  return r;
}, {})

console.log(result)




你可以用这样的简短形式写这个。



const data = [{ name: 'apple',      color: 'red',    hasPeel: false },{ name: 'banana',     color: 'yellow', hasPeel: true },{ name: 'orange',     color: 'orange', hasPeel: true },{ name: 'strawberry', color: 'red',    hasPeel: false }]

const result = data.reduce((r, e) => {
  Object.keys(e).forEach(k => r[k] = [...new Set(r[k]).add(e[k])]);
  return r;
}, {})

console.log(result)




答案 1 :(得分:1)



const input = [{
    name: 'apple',
    color: 'red',
    hasPeel: false
  },
  {
    name: 'banana',
    color: 'yellow',
    hasPeel: true
  },
  {
    name: 'orange',
    color: 'orange',
    hasPeel: true
  },
  {
    name: 'strawberry',
    color: 'red',
    hasPeel: false
  }
];
const result = {};

for (const el of input) {
  for (const [key, value] of Object.entries(el)) {
    if (!result[key]) {
      result[key] = [value];
    } else if (!result[key].includes(value)) {
      result[key].push(value);
    }
  }
}

console.log(result)




答案 2 :(得分:0)

另一种方法是使用reduceforEach功能对includes进行分组和功能,以检查是否重复。

var array = [{ name: 'apple',      color: 'red',    hasPeel: false },{ name: 'banana',     color: 'yellow', hasPeel: true },{ name: 'orange',     color: 'orange', hasPeel: true },{ name: 'strawberry', color: 'red', hasPeel: false }];

var result = array.reduce((a, c) => {
  Object.keys(c).forEach(k => {
    if (!(a[k] || (a[k] = [])).includes(c[k])) a[k].push(c[k]);
  });
  
  return a;
}, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 3 :(得分:0)

很高兴看到你尝试过的问题,以及为什么你发现你的解决方案效率低下。无论如何,这是另一个解决方案,它至少需要ES2018,或者你可以使用babel进行转换。



const data = [{
    name: "apple",
    color: "red",
    hasPeel: false
  },
  {
    name: "banana",
    color: "yellow",
    hasPeel: true
  },
  {
    name: "orange",
    color: "orange",
    hasPeel: true
  },
  {
    name: "strawberry",
    color: "red",
    hasPeel: false
  }
];

const x = [...data.reduce((map, object) => {
  for (let [key, value] of Object.entries(object)) {
    if (map.has(key)) {
      map.get(key).add(value);
    } else {
      map.set(key, new Set([value]));
    }
  }

  return map;
}, new Map())].reduce((object, [key, set]) => ({
  ...object,
  [key]: [...set]
}), {});

console.log(x);