[英]Array of objects, group by object key:value
I have an array of objects like this: 我有一个这样的对象数组:
const data = [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" },
{ id: 8, type: { name: "B" }, condition: "broken" },
{ id: 9, type: { name: "C" }, condition: "broken" }
];
What i'm trying to do is to group those objects by type's key:value
in this case by name:value
, like this: 我想做的是按类型的
key:value
将这些对象分组,在这种情况下,按name:value
进行分组,如下所示:
const data = [
{
by: {
type: { name: "A" }
},
chunks: [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" }
]
},
{
by: {
type: { name: "C" }
},
chunks: [
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 9, type: { name: "C" }, condition: "broken" }
]
},
{
by: {
type: { name: "B" }
},
chunks: [
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 8, type: { name: "B" }, condition: "broken" }
]
},
];
I've tried to use lodash and Array.prototype.reduce()
, my last attempt was using lodash, but i can't get the type as object. 我尝试使用lodash和
Array.prototype.reduce()
,我的最后一次尝试是使用lodash,但我无法将类型作为对象。
_.chain(channels)
.groupBy("type.name")
.map((item, i) => {
return {
chunks: item,
by: i
};
})
.value();
You can use a Map
to collect the data by group, and then its values()
method will iterate the data as you want: 您可以使用
Map
按组收集数据,然后其values()
方法将根据需要迭代数据:
const data = [{ id: 1, type: { name: "A" }, condition: "new" },{ id: 2, type: { name: "C" }, condition: "broken" },{ id: 3, type: { name: "C" }, condition: "brand new" },{ id: 4, type: { name: "B" }, condition: "broken" },{ id: 5, type: { name: "C" }, condition: "brand new" },{ id: 6, type: { name: "A" }, condition: "new" },{ id: 7, type: { name: "A" }, condition: "new" },{ id: 8, type: { name: "B" }, condition: "broken" },{ id: 9, type: { name: "C" }, condition: "broken" }]; const map = new Map(data.map(o => [o.type.name, { by: { type: o.type.name }, chunks: [] }])); data.forEach(o => map.get(o.type.name).chunks.push(o)); const result = [...map.values()]; console.log(result);
Here you go: 干得好:
const data = [ { id: 1, type: { name: "A" }, condition: "new" }, { id: 2, type: { name: "C" }, condition: "broken" }, { id: 3, type: { name: "C" }, condition: "brand new" }, { id: 4, type: { name: "B" }, condition: "broken" }, { id: 5, type: { name: "C" }, condition: "brand new" }, { id: 6, type: { name: "A" }, condition: "new" }, { id: 7, type: { name: "A" }, condition: "new" }, { id: 8, type: { name: "B" }, condition: "broken" }, { id: 9, type: { name: "C" }, condition: "broken" } ]; let names = []; data.forEach(x => { if (names.indexOf(x.type.name)==-1) { names.push(x.type.name); } }); let grouped = names.map(name => ({ by: { type: {name}}, chunks: data.filter(x => x.type.name==name) })); console.log(grouped);
Since you can't group by an object because two objects with the same keys and values are not the same object, you can use JSON.stringify()
to convert the object to a string, and group by it. 由于无法对对象进行分组,因为两个具有相同键和值的对象不是同一对象,因此可以使用
JSON.stringify()
将对象转换为字符串,然后对其进行分组。 Use Array.reduce()
to group the items by the stringified object. 使用
Array.reduce()
按字符串对象对项目进行分组。 Convert to pairs using Object.entries()
, then map the values to an object, and extract the by
value using JSON.parse()
: 使用
Object.entries()
转换为对,然后将值映射到对象,并使用JSON.parse()
提取by
值:
const groupByObj = (arr, key) => Object.entries( arr.reduce((r, o) => { const k = JSON.stringify({ [key]: o[key] }); r[k] = r[k] || []; r[k].push(o); return r; }, {}) ).map(([k, chunks]) => ({ by: JSON.parse(k), chunks })); const data = [{"id":1,"type":{"name":"A"},"condition":"new"},{"id":2,"type":{"name":"C"},"condition":"broken"},{"id":3,"type":{"name":"C"},"condition":"brand new"},{"id":4,"type":{"name":"B"},"condition":"broken"},{"id":5,"type":{"name":"C"},"condition":"brand new"},{"id":6,"type":{"name":"A"},"condition":"new"},{"id":7,"type":{"name":"A"},"condition":"new"},{"id":8,"type":{"name":"B"},"condition":"broken"},{"id":9,"type":{"name":"C"},"condition":"broken"}]; const result = groupByObj(data, 'type'); console.log(result);
You could use reduce
and Object.values
to group like this: 您可以使用
reduce
和Object.values
进行分组,如下所示:
const data = [{"id":1,"type":{"name":"A"},"condition":"new"},{"id":2,"type":{"name":"C"},"condition":"broken"},{"id":3,"type":{"name":"C"},"condition":"brand new"},{"id":4,"type":{"name":"B"},"condition":"broken"},{"id":5,"type":{"name":"C"},"condition":"brand new"},{"id":6,"type":{"name":"A"},"condition":"new"},{"id":7,"type":{"name":"A"},"condition":"new"},{"id":8,"type":{"name":"B"},"condition":"broken"},{"id":9,"type":{"name":"C"},"condition":"broken"}]; const merged = data.reduce((acc, o) => { const {type} = o; acc[type.name] = acc[type.name] || { by: { type }, chunks:[] }; acc[type.name].chunks.push(o) return acc; },{}) const output = Object.values(merged) console.log(output)
(Ignore snippet console
and check browser's console) (忽略代码段
console
并检查浏览器的控制台)
Here the idea is 这里的想法是
name
as key and checks if op
already has that particular key or not. name
作为键,并检查op
已经具有该特定键。 if the key is already there we push the inp
to chunks
property of op. inp
为chunks
属性。 if not we add a new key with by
and chunks
with respective values. by
和chunks
分别添加一个新的键。 const data = [{ id: 1, type: { name: "A" }, condition: "new" },{ id: 2, type: { name: "C" }, condition: "broken" },{ id: 3, type: { name: "C" }, condition: "brand new" },{ id: 4, type: { name: "B" }, condition: "broken" },{ id: 5, type: { name: "C" }, condition: "brand new" },{ id: 6, type: { name: "A" }, condition: "new" },{ id: 7, type: { name: "A" }, condition: "new" },{ id: 8, type: { name: "B" }, condition: "broken" },{ id: 9, type: { name: "C" }, condition: "broken" }]; let op = data.reduce( (op,inp) => { if( op[inp.type] ){ op[inp].chunks.push(inp) } else { op[inp] = { by: {...inp.type}, chunks: [inp] } } return op },{}) console.log(Object.values(op))
Using lodash as you mentioned before we could do: 使用您之前提到的lodash可以做到:
const data = [ { id: 1, type: { name: "A" }, condition: "new" }, { id: 2, type: { name: "C" }, condition: "broken" }, { id: 3, type: { name: "C" }, condition: "brand new" }, { id: 4, type: { name: "B" }, condition: "broken" }, { id: 5, type: { name: "C" }, condition: "brand new" }, { id: 6, type: { name: "A" }, condition: "new" }, { id: 7, type: { name: "A" }, condition: "new" }, { id: 8, type: { name: "B" }, condition: "broken" }, { id: 9, type: { name: "C" }, condition: "broken" } ]; const groups = _.groupBy(data, (val) => val.type.name) const formattedGroupd = Object.keys(groups).map(groupKey => { return { by: {type: { name: groupKey }}, chunks: groups[groupKey] } }); console.log(formattedGroupd)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
You just need to change the way you assing the value to by
in map. 您只需要更改在地图中
by
值的方式即可。 Assign like 分配像
return {
chunks: item,
by: { type: item[0].type}
};
const data = [ { id: 1, type: { name: "A" }, condition: "new" }, { id: 2, type: { name: "C" }, condition: "broken" }, { id: 3, type: { name: "C" }, condition: "brand new" }, { id: 4, type: { name: "B" }, condition: "broken" }, { id: 5, type: { name: "C" }, condition: "brand new" }, { id: 6, type: { name: "A" }, condition: "new" }, { id: 7, type: { name: "A" }, condition: "new" }, { id: 8, type: { name: "B" }, condition: "broken" }, { id: 9, type: { name: "C" }, condition: "broken" } ]; console.log(_.chain(data) .groupBy("type.name") .map((item, i) => { return { by: { type: item[0].type}, chunks: item }; }) .value())
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
const data = [
{ id: 1, type: { name: "A" }, condition: "new" },
{ id: 2, type: { name: "C" }, condition: "broken" },
{ id: 3, type: { name: "C" }, condition: "brand new" },
{ id: 4, type: { name: "B" }, condition: "broken" },
{ id: 5, type: { name: "C" }, condition: "brand new" },
{ id: 6, type: { name: "A" }, condition: "new" },
{ id: 7, type: { name: "A" }, condition: "new" },
{ id: 8, type: { name: "B" }, condition: "broken" },
{ id: 9, type: { name: "C" }, condition: "broken" }
];
const data2 = {};
data.forEach(test => {
if (data2[test.type.name]) {
data2[test.type.name].chunks.push({
test
});
} else {
data2[test.type.name] = {
by: {
type: test.type
},
chunks: [
test
]
};
}
});
console.log(Object.values(data2));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.