拉姆达从数组创建具有固定长度的子数组

时间:2018-10-23 12:50:43

标签: javascript ramda.js

我有一个数据数组,我想将其转换为只有5个元素长的数组。 例如:

[1,2,3,4,5,6] => [1,2,3,4,5]

或者,如果原始数组的内部元素少于5个

[1,2,3] => [1,2,3, undefined, undefined]

(我需要'undefined'val,因为我想稍后对其进行迭代并填充一些默认值)。 那么问题是如何以Ramda方式做到?

谢谢!

1 个答案:

答案 0 :(得分:3)

您可能想对“拉姆达方式”有所警惕。 Ramda(免责声明:我是Ramda的作者之一)只是一个库,一个工具箱。这并不意味着要对如何编写代码进行任何规定,而只是为了使其更易于以某种特定的方式编写... 在适当的情况下

也就是说,使用Ramda编写代码很容易:

const {compose, take, concat, __, repeat} = R

const toFixed = (n, d) => compose(take(n), concat(__, repeat(d, n)))
const take5 = toFixed(5, undefined)

console.log(take5([1, 2, 3, 4, 5, 6])) //=> [1, 2, 3, 4, 5]
console.log(take5([1, 2, 3]))          //=> [1, 2, 3, undefined, undefined]
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

请注意,这可以帮助您在填充时选择该默认值。这可能对您有用,也可能没有用,但是您可以根据需要选择undefined

这并非完全没有意义。可以这样吗?想必。但这是可读的(主要是*),而且我可能不会再走了。

不过,最大的问题是,Ramda在没有库的情况下没有提供很多改进。这是没有Ramda的另一个版本:

const toFixed2 = (n, d) => (xs) => xs.concat(Array(n).fill(d)).slice(0, n)
const brubeck = toFixed2(5, undefined)

console.log(brubeck([1, 2, 3, 4, 5, 6])) //=> [1, 2, 3, 4, 5]
console.log(brubeck([1, 2, 3]))          //=> [1, 2, 3, undefined, undefined]

如果发现Ramda版本更具可读性,并且短一些。但这不是一个巨大的进步。我绝不会仅出于这一小小的改进就将Ramda引入代码库。但是,如果我已经在使用Ramda,我会选择该版本。

更新

对此答案的评论中的讨论提到了另一种解决方案,与问题的评论中的一个有关:

const desmond = (arr) => (arr = arr.slice(0), arr.length = 5, arr)

(如果您不介意更改原始数组,也可以跳过slice步骤。)

这当然具有与上述不同的API,并且不允许您提供默认值。但是还有其他细微的差别。

所有解决方案均获得报告长度为5的数组;它们具有相同的JSON.strigify输出,它们为每个索引报告相同的值,但是:

3 in take5([1, 2, 3])   //=> true
3 in brubeck([1, 2, 3]) //=> true
3 in desmond([1, 2, 3]) //=> false

因此存在明显的差异。最后一个解决方案更改了数组的长度,但没有在丢失的索引上放置任何内容。前两个这样做。鉴于我们要放置的值是undefined,这可能根本不重要,但有时这种微妙之处会刺痛我们。


(*)占位符(__)总是似乎使某些函数对某些函数的可读性降低,而对其他函数则更具可读性。如果愿意,可以将concat(__, foo)替换为flip(concat)(foo)