首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >拉姆达长深

拉姆达长深
EN

Stack Overflow用户
提问于 2017-06-10 13:42:47
回答 4查看 1.7K关注 0票数 1

我有一个一个层次深度的数组,需要计算嵌套数组的长度和,即长度深度。

想出一个很好的惯用的方法和兰达一起做这件事。

我目前的解决办法还不够简洁。可能我漏掉了什么。

你能提出更好的建议吗?

代码语言:javascript
复制
const arr = [[1], [2, 3], [4, 5, 6]]

const lengthDeep = R.pipe(
  R.map(R.prop('length')),
  R.sum
)
console.log(lengthDeep(arr)) // 6
代码语言:javascript
复制
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.24.1/ramda.min.js"></script>

PS:我正在学习Ramda,尝试将它应用到日常编码中。

EN

回答 4

Stack Overflow用户

发布于 2017-06-10 14:10:30

首先,您可以使用R.length而不是R.prop('length')。还可以考虑将数组扁平化,之后所需的结果是该数组的长度:

代码语言:javascript
复制
R.pipe(R.flatten, R.length)
票数 3
EN

Stack Overflow用户

发布于 2017-06-11 02:23:20

虽然这是一个非常直截了当和简单的问题,但我认为这是一个有趣的问题。

到目前为止,有三个建议。我跳过了@ftor的回答,因为它忽略了您关于这是学习Ramda的一部分的评论。但我包括他关于折叠的评论。

以下是解决办法:

代码语言:javascript
复制
const lengthDeep = R.compose(R.sum, R.map(R.length));
const lengthDeep = R.compose(R.length, R.flatten);
const lengthDeep = R.reduce((total, xs) => total + R.length(xs), 0);

(注意,我从pipe切换到了compose。当函数适合于一行时,我通常使用compose,但我并不认为pipecompose是根本不同的解决方案。)

这些都符合对这一问题的不同理解。

Version A (R.compose(R.sum, R.map(R.length)))是最直接的,我认为它最接近于问题的最初表示:我们希望找到“嵌套数组的长度之和”。这个版本是最直接的:它找到这些长度,然后将它们相加在一起。(这是您的版本,通过@trincot的观察,R.length将代替R.prop('length')进行增强。)这是我会选择的。这是相当简单的,很明显它的作用。

Version B (R.compose(R.length, R.flatten))对应于这个问题的一个非常不同的概念。它回答了一个问题,“如果我把所有这些数组组合成一个,它会持续多长时间?”据我所知,它的唯一优点是它是最简单的代码。缺点是,运行可能需要更长的时间,而且肯定需要更多的空间。

Version C (R.reduce((total, xs) => total + R.length(xs), 0))包含了另一个概念。描述此解决方案的最佳方法是使用递归描述。空数组的深度长度为零。第一个元素具有n长度的数组的深度长度是n加上数组其余部分的深度长度。如果你是这么想问题的话,这个版本可能适合你。还有一次您可能会选择使用它:虽然我还没有进行测试,但我希望它具有更好的性能,因为它只在外部列表上循环一次。因此,如果您发现此函数是代码中的瓶颈(在引入任何性能优化之前要测试性能,对吗?),您可能会切换到它,尽管代码要复杂得多。(我不知道是否有一个合理的免费版本。我看不见一个简单的,这已经够可读的了。)

同样,我会选择版本A,除非有重要的事情促使我切换到版本C。不过,这似乎不太可能。

所有这一切可能是一个非常冗长的方式,不同意@ftor的评论:“当您实际使用map时,不应该使用fold数据结构。”相反,我想说的是,您应该使用最简单的代码来匹配问题的心理模型。这必须考虑到其他因素,如性能,但这应该是默认的。我对这个问题的理解完全符合“把所有的长度加在一起”的模式。

票数 2
EN

Stack Overflow用户

发布于 2017-06-11 10:01:49

这里还有一种方法,您可以使用一个名为mapReduce的小助手来实现它--我们可以使用Ramda的curry来实现它,这样它就可以像其他Rambda库成员一样共享一个神奇的咖喱接口。

mapReduce有效地采用了映射函数m和约简函数r,并创建了一个新的约简函数。这是一个有用的通用函数,因为它可以在任何您希望生成减速器的地方使用。

作为额外的奖励,此解决方案将只通过输入数组迭代一次(计算答案的最低要求)。

代码语言:javascript
复制
// mapReduce :: (a -> b) -> ((c, b) -> c) -> ((c, a) -> c)
const mapReduce = curry ((m, r) => 
  (x, y) => r (x, m (y)))

// deepLength :: [[a]] -> Integer
const deepLength = xs =>
  reduce (mapReduce (length, add), 0, xs)

// arr :: [[Integer]]
const arr = [[1], [2, 3], [4, 5, 6]]

console.log (deepLength (arr))
// 6

为了演示mapReduce的多种用途,我将向您展示当事情稍微复杂一些时,它是如何处理的--同时仍然维护一个可读的程序

代码语言:javascript
复制
// mapReduce :: (a -> b) -> ((c, b) -> c) -> ((c, a) -> c)
const mapReduce = curry ((m, r) => 
  (x, y) => r (x, m (y)))

// omap :: (a -> b) -> {k : a} -> {k : b}
const omap = curry ((f, o) =>
  reduce (mapReduce (k => ({ [k]: f(o[k]) }), Object.assign), {}, keys(o)))

console.log (omap (add(10), {a: 1, b: 2, c: 3}))
// {"a": 11, "b": 12, "c": 13}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44473974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档