合并数组中的两个对象

时间:2016-08-09 17:01:32

标签: javascript ecmascript-6

我有这个数组

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"
  }
]

2 个答案:

答案 0 :(得分:4)

我更喜欢这个解决方案,因为它抽象了整理,但允许您使用高阶函数控制如何整理项目。

请注意我们如何对x.id内的x.namenames.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);