给出一组数据:
[
{ 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助手,但还没有找到一种只能迭代一次数组的有效方法。
答案 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)
另一种方法是使用reduce
,forEach
功能对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);