使用 Ramda 减少对象数组的数组

Reduce Array of Array of Objects Using Ramda

我有一个对象数组。我想将其缩减为一个对象数组,并向每个对象再添加一个 属性。 示例输入为:

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

输出应该是:

[{name: 'a', val: 65, rank: 'si'},
 {name: 'b', val: 80, rank: 'dp'},
 {name: 'c', val: 90, rank: 'en'}
 {name: 'd', val: 160, rank: 'fr'}]

Ranka 的静态文本,它将始终是 "si" 如何使用 ramda?

实现此目的

您可以将所有子数组展平为单个数组,按 name 分组,然后映射组,并使用 R.mergeWithKey 将每个组缩减为单个对象以添加 val 属性。使用 R.values 转换回数组,并映射以通过 name.

添加静态排名 属性

请注意,您必须创建一个 Map 或字典对象才能按 name 从中获取排名。

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>