Ramda - 如何分组和转换

Ramda - how to groupBy and transform

我正在尝试按 groupId 对元素进行分组并创建一个新结构。

要分组的元素(出于演示目的,每个组仅包含一个元素,但存在包含多个元素的多个组):

const nodes = [
    {
        "id": 163779,
        "groupId": 0,
        "width": 400,
        "height": 368.28125
    },
    {
        "id": 163783,
        "groupId": 1,
        "width": 216.40625,
        "height": 102.453125
    }
]

我尝试使用 R.groupBy(R.prop('groupId'))(nodes) 并且作为第一步效果很好,结果我得到了:

{
    "0": [
        {
            groupId: 0,
            height: 368.28125,
            id: 163779,
            width: 400
        }
    ],
    "1": [
        {
            groupId: 1,
            height: 102.453125,
            id: 163783,
            width: 216.40625
        }
    ]
}

但是我不知道如何实现这样的结构:

[
  {
    "id": 0,
    "children": [
      {
        "id": 163779,
        "groupId": 0,
        "height": 368.28125,
        "width": 400
      }
    ]
  },
  {
    "id": 1,
    "children": [
      {
        "id": 163783,
        "groupId": 1,
        "height": 102.453125,
        "width": 216.40625
      }
    ]
  }
]

如有任何帮助,我们将不胜感激。谢谢

使用 R.pipe 创建函数。首先按 groupId 分组,然后使用 R.toPairs 转换为 [key, value] 对的数组。使用 R.zipObj.

将数组对映射到所需的形式

const { pipe, groupBy, prop, toPairs, map, zipObj, nth } = R

const fn = pipe(
  groupBy(prop('groupId')), // group by groupId
  toPairs, // convert to an array of [key, value] pairs
  map(zipObj(['id', 'children'])), // map to the required form
)

const nodes = [{"id":163779,"groupId":0,"width":400,"height":368.28125},{"id":163783,"groupId":1,"width":216.40625,"height":102.453125}]

const result = fn(nodes)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

由于R.groupBy将数组转换为以groupId为键的对象,因此groupId被转换为字符串。您可以添加另一个步骤,通过将 id 映射和演化为数字来将其转换回数字:

const { pipe, groupBy, prop, toPairs, map, zipObj, nth, evolve } = R

const fn = pipe(
  groupBy(prop('groupId')), // group by groupId
  toPairs, // convert to an array of [key, value] pairs
  map(zipObj(['id', 'children'])), // map to the required form
  map(evolve({ id: Number })) // convert the id to number if needed
)

const nodes = [{"id":163779,"groupId":0,"width":400,"height":368.28125},{"id":163783,"groupId":1,"width":216.40625,"height":102.453125}]

const result = fn(nodes)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>