拉姆达。从数组创建固定长度的子数组
Ramda. create subarray with fixed length from array
我有一个包含数据的数组,我想将其转换为只有 5 个元素长的数组。
例如:
[1,2,3,4,5,6]
=> [1,2,3,4,5]
或者,如果原始数组中的元素少于 5 个
[1,2,3]
=> [1,2,3, undefined, undefined]
(我需要 'undefined' 值,因为我想稍后迭代它们并填充一些默认值)。
所以问题是如何用 Ramda 的方式来做?
谢谢!!
考虑 "the Ramda way." 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)
我有一个包含数据的数组,我想将其转换为只有 5 个元素长的数组。 例如:
[1,2,3,4,5,6]
=> [1,2,3,4,5]
或者,如果原始数组中的元素少于 5 个
[1,2,3]
=> [1,2,3, undefined, undefined]
(我需要 'undefined' 值,因为我想稍后迭代它们并填充一些默认值)。 所以问题是如何用 Ramda 的方式来做?
谢谢!!
考虑 "the Ramda way." 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)