【问题标题】:How to transform object map to array with Ramda?如何使用 Ramda 将对象映射转换为数组?
【发布时间】:2019-04-26 23:51:36
【问题描述】:

我想转换以下对象:

{
  'id-1': { prop: 'val1' },
  'id-2': { prop: 'val2' },
}

到数组:

[
  { id: 'id-1', prop: 'val1' },
  { id: 'id-2', prop: 'val2' },
]

到目前为止我所做的(有效):

R.pipe(
  R.toPairs,
  R.map(([id, props]) => ({
    id,
    ...props,
  }))
)

如果可能的话,我想只使用 Ramda 来解决它。

【问题讨论】:

  • 到目前为止,您能得到什么?
  • 它按预期工作。我想替换传递给R.map的函数。

标签: javascript functional-programming ramda.js


【解决方案1】:

我建议“仅使用 Ramda”解决它是一个糟糕的设计目标,除非这是学习 Ramda 的练习。我是 Ramda 的创始人之一,也是一个忠实的粉丝,但 Ramda 只是一个工具包,旨在简化你的代码,让它更容易在某个范式中工作。

也就是说,我们当然可以使用 Ramda 编写一个无点版本。我首先想到的是这个*:

const transform = pipe(
  toPairs,
  map(apply(useWith(merge, [objOf('id'), identity])))
)

const data = {'id-1': { prop: 'val1' }, 'id-2': { prop: 'val2'}}

console.log(transform(data))
<script src="https://bundle.run/ramda@0.26.1"></script><script>
const {pipe, toPairs, map, apply, useWith, merge, objOf, identity} = ramda    </script>

但这比你原来的可读性更少,而不是更多。

这段代码:

const transform = pipe(
  toPairs,
  map(([id, props]) => ({...props, id}))
)

非常清晰,而 Ramda 版本需要理解 Ramda 特定的 useWith 和 objOf 以及稍微晦涩的 apply -- 我希望 map、merge 和 identity很清楚。

事实上,这段代码很简单,我可以把它写成单行代码,在这种情况下,我切换到compose 而不是pipe:

const transform = compose(map(([id, props]) => ({...props, id})), toPairs)

但我可能不会这样做,因为我发现多行 pipe 版本更易于阅读。

最后请注意,我们可以在完全不使用任何 Ramda 工具的情况下以相当易读的方式做到这一点:

const transform = (data) => 
  Object.entries(data).map(
    ([id, props]) => ({...props, id})
  )

如果我已经在我的代码库中使用 Ramda,我更喜欢上面的 pipe 版本;我认为它更容易阅读。但绝不会将 Ramda 引入项目中,只是因为差异很小。

我担心人们会迷恋无点代码。这是一个工具。当它使您的代码更易于理解时使用它。当它使您的代码更加晦涩时,请跳过它。在这里,我认为您是从可读性很强的代码开始的;很难改进。


*注意这里identity不是绝对必要的;你可以跳过它而不会受到伤害。由useWith 生成的函数没有identity 将错误地报告数量为1,但由于该函数立即用apply 包装,然后进一步放置在从toPairs 接收二元素数组的上下文中, 没有任何东西依赖于那个数量。但我觉得无论如何都包含它是一个好习惯。

【讨论】:

  • 非常感谢 A 级答案!这涵盖了我关于何时以及何时不使用 Ramda 的所有担忧。作为旁注,我一直在使用 Ramda 进行扩展,以便学习它并了解它的构建块。
【解决方案2】:

这个呢? 可能不那么冗长!

const toArray = R.pipe(
  R.toPairs,
  R.map(
    R.apply(R.assoc('id')),
  ),
);

const data = {
  'id-1': { prop: 'val1' },
  'id-2': { prop: 'val2' },
};

console.log('result', toArray(data));
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"&gt;&lt;/script&gt;

【讨论】:

    猜你喜欢
    • 2019-01-04
    • 2021-11-08
    • 2016-08-30
    • 2019-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    • 2021-05-08
    相关资源
    最近更新 更多