避免在Ramda中双重连接

9
我的问题很简单。最近我开始使用Ramda,我喜欢它,因为它是纯函数式的。但是我有一个小问题,concat函数只接受两个列表作为参数。所以,如果我需要连接三个或更多的列表,我必须像这样链接函数:concat(list1, concat(list2, concat(list3, list4)))(对于四个列表的连接)。我不知道是否有更好的方法来做到这一点?谢谢。

我尝试使用reduce函数,但它返回的是另一个函数而不是列表。你能给我一个例子吗? - Mateus Felipe
1
http://bit.ly/1QRXCGf - dandavis
1
请注意,像这样全部内联执行并没有太多优势,因此在这种情况下,本地方法运行得很好且更短:http://bit.ly/1QRYqLg [r,r2,r3,r4].reduce( (a,b)=>a.concat(b) ) - dandavis
1
使用本地代码怎么样?[].concat(list1, list2, list3, list4)。这样纯粹且看起来更清晰。 - trve.fahad
5个回答

19

如果您想要连接一个列表的列表,您可以使用R.concat函数并将一个空的列表作为初始值来减少列表。

const concatAll = R.reduce(R.concat, []);
concatAll([[1, 2], [3, 4], [5, 6]]);

或者直接将这些列表传递给 R.reduce

R.reduce(R.concat, [], [[1, 2], [3, 4], [5, 6]]);

如果你想要创建一个将每个列表作为单独参数的新可变函数,那么你可以使用 R.unapply 包装函数。

const concatAll_ = R.unapply(R.reduce(R.concat, []));
concatAll_([1, 2], [3, 4], [5, 6]);

Ramda还具有R.unnest函数,当给定一个嵌套列表时,将它们连接在一起。

R.unnest([[1, 2], [3, 4], [5, 6]]);

1
我没有使用过Ramda库,但从您发布的链接中阅读的文档来看,您似乎正在使用node.js。在这种情况下,您可以在node.js中的函数中使用arguments变量编写自己的concat函数,以将n个列表作为输入。 arguments变量本质上是一个包含传递给函数的参数的数组。请注意保留HTML标签。
function myConcat () {
  for (var i = 1; i < arguments.length; i++) {
    concat(arguments[0], arguments[i]);
  }
  return arguments[0];
};

在这种情况下,您可能需要这样调用它:
list1 = myConcat(list1, list2, list3, list4);

1
谢谢你的帮助,但我希望有一种实用的方法来做这件事。@dandavis说得对。 - Mateus Felipe
1
@MateusFelipe 非常棒。对不起,我还没有使用过 Ramda.js。 - hargasinski

1

根据您所连接的内容及环境(需要ES2015),您可以采取以下方法:

 const newList = [...list1, ...list2, ...list3];

否则,您将被困在多次调用concat中,尽管您可以使用compose使其更加简洁:
 const newList = compose(concat(list1), concat(list2), concat(list4))(list3);

真正的问题是你想要映射或者更好的话,缩小范围:
 const newList = reduce((acc, x) => concat(acc, x), [list3], [list4, list2, list1]);

或者内部的 reduce 函数可以看起来像这样:

 (acc, x) => [...acc, ...x]

@ScottChrisopher reduce更加简洁,我忘了将我的concat函数转换为pointfree风格。然而,concat并不是Ramda组合性的一个很好的例子,因为我们可以使用[].concat(a, b, c)原生调用concat函数,这也是ES2015代码[...a, ...b, ...c]通过Babel编译后得到的结果。 - low_ghost

1
使用 R.unnestR.unapply,您可以将函数作为可变参数进行调用:
const unnestAll = R.unapply(R.unnest)
unnestAll([1, 2], [3, 4], [5, 6, 7]) //=> [1, 2, 3, 4, 5, 6, 7]

这是Scott Cristopher的答案的一个小变化。

repl中有示例


1
您可以这样使用flatten方法: R.flatten([list1, list2, list3, list4, ]) 从技术上讲,您需要传递一个包含所有列表的单个数组,然后将它们全部展平为一个数组。
如果您的某些列表可能包含列表本身,请勿使用此方法 - 它们也将被展平。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接