简体   繁体   中英

Merging JSON properties for two arrays of JSON objects (using ramda)

Consider that I have two arrays as follows:

let a1 = [{id:1, name:'jon'}, {id:2, name:'adam'}]
let a2 = [{id:1, age:42}, {id:2, age:13}]

I want to merge the two arrays so the JSON properties get combined into one array; ie this is what I want to end up with:

[{ id: 1, name: 'jon', age: 42 },{ id: 2, name: 'adam', age: 13 }]

Using Ramda I can do the following which gives me close to what I want, but annoyingly it's not in an array - it's all JSON

R.mergeDeepLeft(a1, a2)
{ '0': { id: 1, name: 'yasin', age: 42 },
  '1': { id: 2, name: 'adam', age: 13 } }

I'd do this:

  1. concat a1 and a2 together. (They don't need to be kept apart)
  2. group objects by id and merge those that share the same id.
  3. finally get all merged objects out.

 const res = pipe( concat, reduceBy(mergeLeft, {}, prop('id')), values); console.log( res(a1, a2) ); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.min.js"></script> <script> const {pipe, concat, reduceBy, mergeLeft, values, prop} = R; const a1 = [{id:1, name:'jon'}, {id:2, name:'adam'}]; const a2 = [{id:1, age:42}, {id:2, age:13}]; </script> 

Perhaps not the most elegant nor extensible solution but I'd use some mapping and the spread operator:

let a1 = [{id:1, name:'jon'}, {id:2, name:'adam'}]
let a2 = [{id:1, age:42}, {id:2, age:13}]
let a3 = a1.map(item => {
    return {...item, ...a2.find(item2 => item2.id === item.id)}
})

Here's a working Fiddle for it https://jsfiddle.net/gshfo7pm/

Try this:

 let a1 = [{id:1, name:'jon'}, {id:2, name:'adam'}] let a2 = [{age:13, id:2}, {id:1, age:42}] const fn = R.pipe( R.map(R.indexBy(R.prop('id'))), R.reduce(R.mergeWith(R.mergeDeepLeft), {}), R.values ) let newArray1 = fn([a1, a2]); let newArray2 = fn([a2, a1]); console.log(newArray1); console.log(newArray2); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> 

You can use R.values to convert to array, like this:

let a1 = [{id:1, name:'jon'}, {id:2, name:'adam'}]
let a2 = [{id:1, age:42}, {id:2, age:13}]

R.values(R.mergeWith(R.mergeLeft, a1, a2));

If you have unordered arrays, you can do this:

let a1 = [{id:1, name:'jon'}, {id:2, name:'adam'}]
let a2 = [{id:2, age:13}, {id:1, age:42}]

R.values(R.mergeWith(
  R.mergeLeft, 
  R.indexBy(R.prop('id'), a1), 
  R.indexBy(R.prop('id'), a2)
));
let concatValues = (k, l, r) =>  r
R.mergeDeepWithKey(concatValues,a1,a2)

will produce this

{"0": {"age": 42, "id": 1, "name": "jon"}, "1": {"age": 13, "id": 2, "name": "adam"}}

it's not exact output but you can start with this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM