我要合并/合并数组中的对象,每个对象都带有一系列嵌套数组。我想基于特定键(此处为label[1]
)合并对象。我可以使用Lodash和unionBy来过滤label[1]
所产生的重复项,但是如何保留已过滤项的值?
数组看起来像这样:
var arr = [{
"label": ['item', 'private'],
"values": [1, 2, 3]
},
{
"label": ['item', 'private'],
"values": [1, 2, 3, 6]
},
{
"label": ['item', 'work'],
"values": [1, 2, 8, 9]
},
{
"label": ['item', 'private'],
"values": [1, 2, 4, 5]
},
{
"label": ['item', 'school'],
"values": [1, 2, 7]
}
];
所需的输出是:
var arr = [{
"label": ["item", "private"],
"values": [1, 2, 3, 4, 5, 6 ]
}, {
"label": ["item", "work"],
"values": [1, 2, 8, 9]
}, {
"label": ["item", "school"],
"values": [1, 2, 7]
}]
这里是一个样本,距离样本只有一半。
var arr = [
{ label: ['item','private'], values: [1,2,3] },
{ label: ['item','private'], values: [1,2,3,6] },
{ label: ['item','work'], values: [1,2,8,9] },
{ label: ['item','private'], values: [1,2,4,5] },
{ label: ['item','school'], values: [1,2,7] }
];
var result = _.unionBy(arr, "label[1]");
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
有什么想法吗?
谢谢 拉瑟
答案 0 :(得分:1)
我会写:
const arr2 = _(arr)
.groupBy("label")
.map(objs => ({
label: objs[0].label,
values: _(objs).flatMap("values").uniq().value(),
}))
.value()
答案 1 :(得分:0)
不确定如何使用lodash进行此操作,但我不认为unionBy仍然是执行此操作的方法。
在这里,您可以使用lodash按标签进行分组,然后将组减少为一个值以合并组中的项目。
const arr = [{"label":["item","private"],"values":[1,2,3]},{"label":["item","private"],"values":[1,2,3,6]},{"label":["item","work"],"values":[1,2,8,9]},{"label":["item","private"],"values":[1,2,4,5]},{"label":["item","school"],"values":[1,2,7]}];
console.log(
Object.values(
_.groupBy(arr, (item) => item.label.join()),//use lodash group by
).map((
group, //now we have array of array of groups
) =>
group
.reduce((result, item) => ({
//reduce a group to one object
label: result.label, //set label
values: [
//set values with unique values of all items
...new Set(
(result.values || []).concat(item.values || []),
),
],
})),
),
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
答案 2 :(得分:0)
您还可以通过 lodash 做类似的事情:
var arr = [{ "label": ['item', 'private'], "values": [1, 2, 3] }, { "label": ['item', 'private'], "values": [1, 2, 3, 6] }, { "label": ['item', 'work'], "values": [1, 2, 8, 9] }, { "label": ['item', 'private'], "values": [1, 2, 4, 5] }, { "label": ['item', 'school'], "values": [1, 2, 7] } ]
const merge = arr => _.reduce(arr, (r,c) => _.union(r, c.values), [])
const result = _(arr).groupBy('label')
.entries()
.reduce((r,[k,v]) => (r.push({ label: k.split(','), values: merge(v) }), r), [])
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
这个想法是首先通过_.groupBy
进行分组,然后(通过_.entries
获取条目,以便可以通过_.reduce
形成所需的输出。 _.union
,我们将值数组合并为最终reduce
的一部分。
这是 ES6 的实现:
var arr = [{ "label": ['item', 'private'], "values": [1, 2, 3] }, { "label": ['item', 'private'], "values": [1, 2, 3, 6] }, { "label": ['item', 'work'], "values": [1, 2, 8, 9] }, { "label": ['item', 'private'], "values": [1, 2, 4, 5] }, { "label": ['item', 'school'], "values": [1, 2, 7] } ]
const mrg = arr => Array.from(new Set(arr.reduce((r,c) => [...r, ...c.values], [])))
const grp = (arr, k) => arr.reduce((r,c) => (r[c[k]] = [...r[c[k]] || [], c], r), {})
const result = Object.entries(grp(arr, 'label'))
.reduce((r,[k,v]) => (r.push({ label: k.split(','), values: mrg(v) }), r), [])
console.log(result)