如何使用 Ramda 将对象映射转换为数组?
How to transform object map to array with Ramda?
我想从以下对象转换:
{
'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 解决它 - 如果可能的话。
我建议解决它 "using Ramda only" 是一个糟糕的设计目标,除非这是学习 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}))
)
是 crystal-清楚的,而 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
的函数将错误地报告 arity 为 1,但是由于该函数立即用 apply
包装,然后进一步放置在接收二元数的上下文中来自 toPairs
的元素数组,没有任何依赖于该元数的东西。但我觉得无论如何都包含它是一个好习惯。
这个呢?
可能不那么冗长!
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));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
我想从以下对象转换:
{
'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 解决它 - 如果可能的话。
我建议解决它 "using Ramda only" 是一个糟糕的设计目标,除非这是学习 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}))
)
是 crystal-清楚的,而 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
的函数将错误地报告 arity 为 1,但是由于该函数立即用 apply
包装,然后进一步放置在接收二元数的上下文中来自 toPairs
的元素数组,没有任何依赖于该元数的东西。但我觉得无论如何都包含它是一个好习惯。
这个呢? 可能不那么冗长!
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));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>