Reputation: 600
I have an array of array of objects. I want to reduce that to an array of object and adding one more property to each object. The sample input is:
const data = [
[
{name:"a", val:5},
{name:"b", val:10},
{name:"c", val:20},
{name:"d", val:50},
{name:"e", val:100}
],
[
{name:"a", val:0},
{name:"b", val:20},
{name:"c", val:30},
{name:"d", val:40},
{name:"e", val:10}
],
[
{name:"a", val:60},
{name:"b", val:50},
{name:"c", val:40},
{name:"d", val:70},
{name:"e", val:30}
]
];
And the Output should be:
[{name: 'a', val: 65, rank: 'si'},
{name: 'b', val: 80, rank: 'dp'},
{name: 'c', val: 90, rank: 'en'}
{name: 'd', val: 160, rank: 'fr'}]
Rank
is static text means for a
, it will always be "si"
How can I achieve this using ramda?
Upvotes: 1
Views: 1259
Reputation: 191986
You can convert flatten all sub arrays to a single array, group by the name
, and then map the groups, and reduce each group to a single object using R.mergeWithKey to add the val
property. Convert back to an array using R.values, and map to add the static ranks property by name
.
Note that you must create a Map or a dictionary object to take the rank by name
from.
const { mergeWithKey, pipe, flatten, groupBy, prop, map, reduce, values } = R
const ranks = new Map([['a', 'si'], ['b', 'dp'], ['c', 'en'], ['d', 'fr']])
// merge deep and combine val property values
const combine = mergeWithKey((k, l, r) => k == 'val' ? l + r : r)
const mergeData = pipe(
flatten, // flatten to a single array
groupBy(prop('name')), // group by the name
map(reduce(combine, {})), // combine each group to a single object
values, // convert back to array
map(o => ({ ...o, rank: ranks.get(o.name) })), // add the static rank property
)
const data = [[{"name":"a","val":5},{"name":"b","val":10},{"name":"c","val":20},{"name":"d","val":50},{"name":"e","val":100}],[{"name":"a","val":0},{"name":"b","val":20},{"name":"c","val":30},{"name":"d","val":40},{"name":"e","val":10}],[{"name":"a","val":60},{"name":"b","val":50},{"name":"c","val":40},{"name":"d","val":70},{"name":"e","val":30}]]
const results = mergeData(data)
console.log(results)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
Upvotes: 3