使用 Lodash,如何将这些数据转换为所需的格式?
Using Lodash, how can I transform this data to the desired format?
我对 lodash 还很陌生,我怀疑它可以帮助我以我想要的方式转换我的数据。我一直在阅读 lodash docs,但老实说它并没有深入,我没有看到我需要的正确操作组合。
这是我想要做的:
var configs = [ {
configId: 1,
options: [ {categoryId: 1, id: 100},
{categoryId: 2, id: 200},
{categoryId: 3, id: 300} ] },
{
configId: 2,
options: [ {categoryId: 1, id: 105},
{categoryId: 2, id: 210} ] },
{
configId: 3,
options: [ {categoryId: 2, id: 200},
{categoryId: 1, id: 165},
{categoryId: 3, id: 300} ] }
];
// I want the above to look like this:
/*
[ {categoryId: 1, ids: [100, 105, 165]},
{categoryId: 2, ids: [200, 210]},
{categoryId: 3, ids: [300]} ]
*/
这里是 fiddle 如果你想试验的话。
当我看问题时我想我想:
- 合并所有
configs
个对象,这样我就有了一大堆 options
个对象
- 分组依据
categoryId
- 然后我真的迷路了...我怀疑我可以在这里使用 reduce(),但我也认为我需要一个 map() 来实际生成转换后的对象。
无论如何,我一直在循环,没有取得进展,我希望有人能给我指出正确的方向。
使用 ES2015 语法:
_.map(
_.groupBy(_.flatMap(configs, config => config.options), 'categoryId'),
(val, key) => ({categoryId: key, ids: _.uniq(_.map(val, v => v.id)) })
)
ES5 兼容(由 Babel 生成):
_.map(
_.groupBy(
_.flatMap(configs, function (config) {
return config.options;
}),
'categoryId'),
function (val, key) {
return {
categoryId: key,
ids: _.uniq(_.map(val, function (v) {
return v.id;
}))
};
});
解释:
_.flatMap(configs, config => config.options)
从每个配置对象中获取 options
数组,将它们展平为单个 [{categoryId: xx, id: yy}, ...]
数组
[ {categoryId:1,id:100},
{categoryId:2,id:200},
{categoryId:3,id:300},
{categoryId:1,id:105},
{categoryId:2,id:210},
{categoryId:2,id:200},
{categoryId:1,id:165},
{categoryId:3,id:300} ]
_.groupBy(..., 'categoryId')
按 categoryId
在数组上方分组,如 [{xx: [categoryId: xx, id: yy}, ...]
{
1:[
{categoryId:1,id:100},
{categoryId:1,id:105},
{categoryId:1,id:165} ],
2:[
{categoryId:2,id:210},
{categoryId:2,id:200},
{categoryId:2,id:200} ],
3:[
{categoryId:3,id:300},
{categoryId:3,id:300} ] }
_.map(..., (val, key) => ({categoryId: key, ids: _.uniq(_.map(val, v => v.id)) }))
接收 val = [{xx: [categoryId: xx, id: yy}, ...]
、key: xx
并将它们映射到对象,其中 categoryId
设置为接收到的键,ids
到唯一的 id
数组来自分组的对象。结果是你想要的数组。
[ {
categoryId:1,
ids:[100,105,165]},
{
categoryId:2,
ids:[200,210]},
{
categoryId:3,
ids:[300]}]
var configs = [{
configId: 1,
options: [
{categoryId: 1, id: 100},
{categoryId: 2, id: 200},
{categoryId: 3, id: 300}
]
}, {
configId: 2,
options: [
{categoryId: 1, id: 105},
{categoryId: 2, id: 210}
]
}, {
configId: 3,
options: [
{categoryId: 2, id: 200},
{categoryId: 1, id: 165},
{categoryId: 3, id: 300}
]
}];
var result = _.chain(configs)
.flatMap(config => config.options)
.groupBy(id => id.categoryId)
.map((list, categoryId) => ({
categoryId: +categoryId,
ids: _.chain(list)
.map(x => x.id)
.uniq()
.value()
}))
.value();
document.body.textContent = JSON.stringify(result,null,2);
body {
white-space: pre-wrap;
}
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.js"></script>
我对 lodash 还很陌生,我怀疑它可以帮助我以我想要的方式转换我的数据。我一直在阅读 lodash docs,但老实说它并没有深入,我没有看到我需要的正确操作组合。
这是我想要做的:
var configs = [ {
configId: 1,
options: [ {categoryId: 1, id: 100},
{categoryId: 2, id: 200},
{categoryId: 3, id: 300} ] },
{
configId: 2,
options: [ {categoryId: 1, id: 105},
{categoryId: 2, id: 210} ] },
{
configId: 3,
options: [ {categoryId: 2, id: 200},
{categoryId: 1, id: 165},
{categoryId: 3, id: 300} ] }
];
// I want the above to look like this:
/*
[ {categoryId: 1, ids: [100, 105, 165]},
{categoryId: 2, ids: [200, 210]},
{categoryId: 3, ids: [300]} ]
*/
这里是 fiddle 如果你想试验的话。
当我看问题时我想我想:
- 合并所有
configs
个对象,这样我就有了一大堆options
个对象 - 分组依据
categoryId
- 然后我真的迷路了...我怀疑我可以在这里使用 reduce(),但我也认为我需要一个 map() 来实际生成转换后的对象。
无论如何,我一直在循环,没有取得进展,我希望有人能给我指出正确的方向。
使用 ES2015 语法:
_.map(
_.groupBy(_.flatMap(configs, config => config.options), 'categoryId'),
(val, key) => ({categoryId: key, ids: _.uniq(_.map(val, v => v.id)) })
)
ES5 兼容(由 Babel 生成):
_.map(
_.groupBy(
_.flatMap(configs, function (config) {
return config.options;
}),
'categoryId'),
function (val, key) {
return {
categoryId: key,
ids: _.uniq(_.map(val, function (v) {
return v.id;
}))
};
});
解释:
_.flatMap(configs, config => config.options)
从每个配置对象中获取 options
数组,将它们展平为单个 [{categoryId: xx, id: yy}, ...]
[ {categoryId:1,id:100},
{categoryId:2,id:200},
{categoryId:3,id:300},
{categoryId:1,id:105},
{categoryId:2,id:210},
{categoryId:2,id:200},
{categoryId:1,id:165},
{categoryId:3,id:300} ]
_.groupBy(..., 'categoryId')
按 categoryId
在数组上方分组,如 [{xx: [categoryId: xx, id: yy}, ...]
{
1:[
{categoryId:1,id:100},
{categoryId:1,id:105},
{categoryId:1,id:165} ],
2:[
{categoryId:2,id:210},
{categoryId:2,id:200},
{categoryId:2,id:200} ],
3:[
{categoryId:3,id:300},
{categoryId:3,id:300} ] }
_.map(..., (val, key) => ({categoryId: key, ids: _.uniq(_.map(val, v => v.id)) }))
接收 val = [{xx: [categoryId: xx, id: yy}, ...]
、key: xx
并将它们映射到对象,其中 categoryId
设置为接收到的键,ids
到唯一的 id
数组来自分组的对象。结果是你想要的数组。
[ {
categoryId:1,
ids:[100,105,165]},
{
categoryId:2,
ids:[200,210]},
{
categoryId:3,
ids:[300]}]
var configs = [{
configId: 1,
options: [
{categoryId: 1, id: 100},
{categoryId: 2, id: 200},
{categoryId: 3, id: 300}
]
}, {
configId: 2,
options: [
{categoryId: 1, id: 105},
{categoryId: 2, id: 210}
]
}, {
configId: 3,
options: [
{categoryId: 2, id: 200},
{categoryId: 1, id: 165},
{categoryId: 3, id: 300}
]
}];
var result = _.chain(configs)
.flatMap(config => config.options)
.groupBy(id => id.categoryId)
.map((list, categoryId) => ({
categoryId: +categoryId,
ids: _.chain(list)
.map(x => x.id)
.uniq()
.value()
}))
.value();
document.body.textContent = JSON.stringify(result,null,2);
body {
white-space: pre-wrap;
}
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.js"></script>