我有三个对象:
{a:1,b:2}, {a:11, b:22}, { a: 111 }
我想得到:
{a: [1, 11, 111], b: [2, 22]}
我们看到这就像groupBy
,但我无法找到如何对对象执行此操作。我写了做这个的复杂事情:
const mergeValuesByKey = (...objects) =>
_.mapValues(
_.groupBy(
_.flatten(objects.map((obj) => Object.entries(obj))).map((pair) =>
_.fromPairs([pair])
),
(singleElementObject) => Object.keys(singleElementObject)[0]
),
(singleValueObjects) =>
singleValueObjects.map(
(singleValueObject) => Object.values(singleValueObject)[0]
)
);
有什么比这更简单的吗?也许来自lodash的一种方法?
与成对使用_.flatMap()
以获取[键,值]的数组。用_.head()
(键)对对分组。使用_.mapValues()
通过_.last()
(值)映射每个组。
const mergeValuesByKey = (...objects) => {
const pairs = _.flatMap(objects, _.toPairs); // get an array of pairs
const groups = _.groupBy(pairs, _.head); // group them by the key
return _.mapValues(groups, g => g.map(_.last)); // map each group to an array of values
}
const result = mergeValuesByKey({a:1,b:2}, {a:11, b:22}, { a: 111 })
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
使用lodash / fp,您可以使用_.rest()
和_.flow()
生成具有相同功能的无点功能:
const { rest, flow, flatMap, toPairs, groupBy, head, mapValues, map, last } = _
const mergeValuesByKey = rest(flow(
flatMap(toPairs),
groupBy(head),
mapValues(map(last)),
))
const result = mergeValuesByKey({a:1,b:2}, {a:11, b:22}, { a: 111 })
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>
这里是一个javascript解决方案,我们已经使用传播语法并使用array#reduce
遍历数组将所有对象分组到一个数组中。对于每个对象,我们迭代其所有键,并创建一个新表并将所有值添加到数组中。
const mergeValueByKeys = (...objects) => objects.reduce((r, o) => {
Object.keys(o).forEach(k => {
r[k] = r[k] || [];
r[k].push(o[k]);
});
return r;
}, {});
console.log(mergeValueByKeys({ a: 1, b: 2 }, { a: 11, b: 22 }, {a: 111}));