我有一个对象数组,我需要转换为新对象。 一些值作为键和一个值数组。
const data = [
{
type: 'user',
id: 1
},
{
type: 'user',
id: 2
},
{
type: 'group',
id: 1
},
{
type: 'group',
id: 2
},
{
type: 'user',
id: 3
},
{
type: 'user',
id: 4
}
]
期望的结果是
const result = {
user: [1, 2, 3, 4],
group: [1, 2]
}
我尝试使用reduced
但不是我期望的。
const result = data.reduce((acc, { type, ...obj }) => {
acc[type] = data.map(item => item.id)
return acc;
}, {})
result = { user: [ 1, 2, 1, 2, 3, 4 ], group: [ 1, 2, 1, 2, 3, 4 ] }
每次迭代,你检查累加对象是否具有类型,如果是,则将迭代元素的 id 推送到现有数组,否则初始化数组
const data = [
{
type: "user",
id: 1,
},
{
type: "user",
id: 2,
},
{
type: "group",
id: 1,
},
{
type: "group",
id: 2,
},
{
type: "user",
id: 3,
},
{
type: "user",
id: 4,
},
]
const res = data.reduce((acc, el) => {
if (acc[el.type]) {
acc[el.type].push(el.id)
} else {
acc[el.type] = [el.id]
}
return acc
}, {})
console.log(res)
除非你使用预定义的化简器函数进行函数式编程,否则reduce
通常是一个过于复杂的工具。只需使用循环。
在这种情况下,您将从一个具有user
和group
属性的对象开始,这些属性具有空数组,然后使用动态属性名称添加到正确的数组:
const result = { user: [], group: [] };
for (const {type, id} of data) {
result[type].push(id);
}
现场示例:
const data = [
{
type: 'user',
id: 1
},
{
type: 'user',
id: 2
},
{
type: 'group',
id: 1
},
{
type: 'group',
id: 2
},
{
type: 'user',
id: 3
},
{
type: 'user',
id: 4
}
];
const result = { user: [], group: [] };
for (const {type, id} of data) {
result[type].push(id);
}
console.log(result);
如果事先不知道type
值,请动态添加数组:
const result = { user: [], group: [] };
for (const {type, id} of data) {
if (!result[type]) {
result[type] = [];
}
result[type].push(id);
}
现场示例:
const data = [
{
type: 'user',
id: 1
},
{
type: 'user',
id: 2
},
{
type: 'group',
id: 1
},
{
type: 'group',
id: 2
},
{
type: 'user',
id: 3
},
{
type: 'user',
id: 4
}
];
const result = { user: [], group: [] };
for (const {type, id} of data) {
if (!result[type]) {
result[type] = [];
}
result[type].push(id);
}
console.log(result);
如果你喜欢非常简洁,你可以使用新的??=
运算符在数组还没有的时候添加数组(对我来说,在这种情况下,它走得太远了,失去了清晰度):
const result = { user: [], group: [] };
for (const {type, id} of data) {
(result[type] ??= []).push(id);
}
现场示例:
const data = [
{
type: 'user',
id: 1
},
{
type: 'user',
id: 2
},
{
type: 'group',
id: 1
},
{
type: 'group',
id: 2
},
{
type: 'user',
id: 3
},
{
type: 'user',
id: 4
}
];
const result = { user: [], group: [] };
for (const {type, id} of data) {
(result[type] ??= []).push(id);
}
console.log(result);
你可以把它硬塞进一个reduce
(因为你可以把任何数组操作硬塞进一个reduce
),但这样做并不能给你带来任何东西。这是第一个使用reduce
而不是循环:
const result = data.reduce((acc, {type, id}) => {
acc[type].push(id);
return acc;
}, {user: [], group: []});
const data = [
{
type: 'user',
id: 1
},
{
type: 'user',
id: 2
},
{
type: 'group',
id: 1
},
{
type: 'group',
id: 2
},
{
type: 'user',
id: 3
},
{
type: 'user',
id: 4
}
];
const result = data.reduce((acc, {type, id}) => {
acc[type].push(id);
return acc;
}, {user: [], group: []});
console.log(result);
您需要检查该属性是否存在并向其推送id
。
const
data = [{ type: 'user', id: 1 }, { type: 'user', id: 2 }, { type: 'group', id: 1 }, { type: 'group', id: 2 }, { type: 'user', id: 3 }, { type: 'user', id: 4 }],
result = data.reduce((acc, { type, id }) => {
acc[type] ??= [];
acc[type].push(id);
return acc;
}, {});
console.log(result);
如果累加器上不存在该属性,请添加它,并且如果它确实将id
推送到其中:
const data = [{"type":"user","id":1},{"type":"user","id":2},{"type":"group","id":1},{"type":"group","id":2},{"type":"user","id":3},{"type":"user","id":4}];
const result = data.reduce((acc, { type, id }) => {
if(!acc[type]) acc[type] = [];
acc[type].push(id);
return acc;
}, {})
console.log(result)
这个怎么样?
groupBy()
的香草版本
const groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x.id);
return rv;
}, {});
};
您可以使用以下方法通过键轻松调用组:
const result = groupBy(data, 'type');
完整代码:
const groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x.id);
return rv;
}, {});
};
const data = [
{
type: 'user',
id: 1
},
{
type: 'user',
id: 2
},
{
type: 'group',
id: 1
},
{
type: 'group',
id: 2
},
{
type: 'user',
id: 3
},
{
type: 'user',
id: 4
}
]
const result = groupBy(data, 'type');
console.log(result); // { group: [1, 2], user: [1, 2, 3, 4] }
参考链接。
这是一个使用Object.fromEntries
为结果对象构建框架的解决方案(使用空数组)。然后,一个简单的循环可以填充这些数组,你就完成了:
let data = [{ type: 'user', id: 1 }, { type: 'user', id: 2 }, { type: 'group', id: 1 }, { type: 'group', id: 2 }, { type: 'user', id: 3 }, { type: 'user', id: 4 }];
let result = Object.fromEntries(data.map(({type}) => [type, []]));
for (let {type, id} of data) result[type].push(id);
console.log(result);