我有很多人在不同的年份买了车。 简化的数组是这样的:
const owners = [{
name: "john",
hasCar: true,
yearBought: 2002
}, {
name: "john",
hasCar: true,
yearBought: 2005
}, {
name: "mary",
hasCar: true,
yearBought: 2015
}, {
name: "john",
hasCar: true,
yearBought: 2018
}]
如果一个人拥有一辆以上的汽车(例如本例中的John),那么在购买汽车的年份不同的人会有不同的对象。我想合并属于每个人的对象,最终结果应该像这样:
const owners = [{
name: "john",
hasCar: true,
yearBought: [2002, 2005, 2018]
}, {
name: "mary",
hasCar: true,
yearBought: 2018
}]
答案 0 :(得分:1)
您可以使用reduce
数组,并根据name
首先对其进行分组。累加器是一个对象,每个唯一的name
作为键。如果name
已经存在,请使用concat
将它们推入数组。否则,在累加器中创建一个新密钥并将其设置为当前对象。然后,使用Object.values()
将数组的值作为数组获取
const owners = [{name:"john",hasCar:!0,yearBought:2002},{name:"john",hasCar:!0,yearBought:2005},{name:"mary",hasCar:!0,yearBought:2015},{name:"john",hasCar:!0,yearBought:2018}];
const merged = owners.reduce((r, o) => {
if(r[o.name])
r[o.name].yearBought = [].concat(r[o.name].yearBought, o.yearBought)
else
r[o.name] = o;
return r;
},{})
console.log(Object.values(merged))
答案 1 :(得分:0)
您可以使用普通的javascript来代替loadash
。
尝试一下:
const owners = [{
name: "john",
hasCar: true,
yearBought: 2002
}, {
name: "john",
hasCar: true,
yearBought: 2005
}, {
name: "mary",
hasCar: true,
yearBought: 2015
}, {
name: "john",
hasCar: true,
yearBought: 2018
}]
let tmpList = [];
let result = [];
for (var i = 0; i < owners.length; i++) {
if (tmpList.indexOf(owners[i].name) == -1) {
tmpList.push(owners[i].name);
result.push(owners[i]);
result[result.length-1].yearBought = [result[result.length-1].yearBought];
for (var j = 0; j < owners.length; j++) {
if (i != j && owners[i].name == owners[j].name) {
result[result.length-1].yearBought.push(owners[owners.length-1].yearBought);
}
}
}
}
console.log(result);
答案 2 :(得分:0)
只需使用reduce
:
const owners = [{name:"john",hasCar:true,yearBought:2002},{name:"john",hasCar:true,yearBought:2005},{name:"mary",hasCar:true,yearBought:2015},{name:"john",hasCar:true,yearBought:2018}];
const newOwners = Object.values(owners.reduce((acc, curr) => {
acc[curr.name] = acc[curr.name] ? { ...acc[curr.name], yearBought: [].concat(acc[curr.name].yearBought, curr.yearBought) } : curr;
return acc;
}, {}));
console.log(newOwners);
答案 3 :(得分:0)
我希望此帮助使用 PURE lodash函数 ..它看起来干净且可读。
var array = [{
name: "john",
hasCar: true,
yearBought: 2002
}, {
name: "john",
hasCar: true,
yearBought: 2005
}, {
name: "mary",
hasCar: true,
yearBought: 2015
}, {
name: "john",
hasCar: true,
yearBought: 2018
}]
function mergeNames(arr) {
return Object.values(_.chain(arr).groupBy('name').mapValues((g) => (_.merge(...g, {
yearBought: _.map(g, 'yearBought')
}))).value());
}
console.log(mergeNames(array));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
谢谢:)
答案 4 :(得分:0)
您可以使用唯一键(在您的情况下为name
对项目进行分组,然后映射组,并合并每个组中的项目:
const { flow, partialRight: pr, groupBy, map, mergeWith, concat, isUndefined } = _
const mergeDuplicates = (isCollected, key) => flow(
pr(groupBy, key), // group by the unique key
pr(map, group => mergeWith({}, ...group,
(o, s, k) => isCollected(k) && !isUndefined(o) ? concat(o, s) : s
)) // merge each group to a new object
)
const owners = [{name:"john",hasCar:true,yearBought:2002},{name:"john",hasCar:true,yearBought:2005},{name:"mary",hasCar:!0,yearBought:2015},{name:"john",hasCar:true,yearBought:2018}]
const isCollected = key => key === 'yearBought'
const result = mergeDuplicates(isCollected, 'name')(owners)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
还有lodash / fp版本:
const { flow, groupBy, map, mergeAllWith, cond, nthArg, concat } = _
const mergeDuplicates = (isCollected, key) => flow(
groupBy(key),
map(mergeAllWith(cond([[
flow(nthArg(2), isCollected),
concat,
nthArg(1)
]])))
)
const owners = [{name:"john",hasCar:!0,yearBought:2002},{name:"john",hasCar:!0,yearBought:2005},{name:"mary",hasCar:!0,yearBought:2015},{name:"john",hasCar:!0,yearBought:2018}]
const isCollected = key => key === 'yearBought'
const result = mergeDuplicates(isCollected, 'name')(owners)
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)'></script>