newbie
newbie

Reputation: 600

Reduce Array of Array of Objects Using Ramda

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

Answers (1)

Ori Drori
Ori Drori

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

Related Questions