我有这个数组
var arr1 = [{id: 1, name: "lorem"}, {id: 1, name: "ipsum"}, {id: 2, name: "dolor"}]
你可以在这里看到他们得到相同id
的前2个索引,我希望输出是这样的
newArr
[
{
id: 1,
name: ["lorem", "ipsum"]
},
{
id: 2,
name: "dolor"
}
]
答案 0 :(得分:4)
我更喜欢这个解决方案,因为它抽象了整理,但允许您使用高阶函数控制如何整理项目。
请注意我们如何对x.id
内的x.name
或names.concat([name])
或collateBy
进行任何说明。此过程不了解您可能正在整理的种数据。
// generic collation procedure
const collateBy = f => g => xs => {
return xs.reduce((m,x) => {
let v = f(x)
return m.set(v, g(m.get(v), x))
}, new Map())
}
// reusable collateById procedure
const collateById = collateBy (x => x.id)
// custom concatNames procedure
// note use of `{name:[]}` which is the "seed" value for an empty collation
const concatNames = xs=> {
let collation = collateById ((a={name:[]}, b) =>
Object.assign(a, b, { name: [...a.name, b.name] })
) (xs)
return Array.from(collation.values())
}
// sample data
let arr1 = [
{id: 1, name: "lorem"},
{id: 1, name: "ipsum"},
{id: 2, name: "dolor"}
]
console.log(concatNames (arr1))
高阶函数演示了collateBy
这样的通用程序的强大功能。这是使用完全相同的collateBy
过程但执行非常不同的排序规则的另一个示例
const collateBy = f => g => xs => {
return xs.reduce((m,x) => {
let v = f(x)
return m.set(v, g(m.get(v), x))
}, new Map())
}
const collateEvenOdd = collateBy (x => x % 2 === 0 ? 'even' : 'odd')
const sumEvenOdd = collateEvenOdd ((a=0, b) => a + b)
let data = [2,3,4,5,6,7]
let collation = sumEvenOdd (data)
let even = collation.get('even')
let odd = collation.get('odd')
console.log('even sum', even) // 2 + 4 + 6 === 12
console.log('odd sum', odd) // 3 + 5 + 7 === 15
答案 1 :(得分:2)
使用缩小和地图,您可以轻松地将其转换为您想要的内容
var arr1 = [{id: 1, name: "lorem"}, {id: 1, name: "ipsum"}, {id: 2, name: "dolor"}];
var obj = arr1.reduce((a,b) => (b.id in a?a[b.id].push(b.name):a[b.id]=[b.name],a),{}),
newArr = Object.keys(obj).map( id => ({id, name : obj[id]}));
console.log(newArr);