避免在 Ramda 中进行双重连接
Avoid double concat in Ramda
我的问题很简单。我最近开始使用 Ramda,我喜欢它,因为它是纯函数式的。 concat 函数有点问题,因为它只接受两个列表作为参数。因此,如果我需要连接三个或更多列表,我必须像这样链接函数:concat(list1, concat(list2, concat(list3, list4)))
(用于四个列表连接)。有没有更好的方法来做到这一点,我不知道?谢谢
我没有使用过 Ramda 库,但从我在您发布的 link 中阅读的文档来看,您似乎在 node.js 中使用了它。在这种情况下,您可以在 node.js
中的函数中使用 arguments
变量来编写您自己的 concat
函数,该函数将 n 个列表作为输入。 arguments
变量本质上是输入到函数中的参数数组。
function myConcat () {
for (var i = 1; i < arguments.length; i++) {
concat(arguments[0], arguments[i]);
}
return arguments[0];
};
但是在这种情况下,您可能不得不这样称呼它:
list1 = myConcat(list1, list2, list3, list4);
具体取决于您连接的内容和您的环境(需要 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]
如果您想连接一个列表列表,您可以使用 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]]);
将 R.unnest
与 R.unapply
结合使用允许您将函数作为可变参数调用:
const unnestAll = R.unapply(R.unnest)
unnestAll([1, 2], [3, 4], [5, 6, 7]) //=> [1, 2, 3, 4, 5, 6, 7]
略有不同
您可以这样使用flatten
方法:
R.flatten([list1, list2, list3, list4, ])
从技术上讲,您传递的是一个包含所有列表的数组。然后你只需将它们全部压平成一个数组。
如果您的某些列表本身可能包含列表,请不要使用此方法 - 它们也会被展平。
我的问题很简单。我最近开始使用 Ramda,我喜欢它,因为它是纯函数式的。 concat 函数有点问题,因为它只接受两个列表作为参数。因此,如果我需要连接三个或更多列表,我必须像这样链接函数:concat(list1, concat(list2, concat(list3, list4)))
(用于四个列表连接)。有没有更好的方法来做到这一点,我不知道?谢谢
我没有使用过 Ramda 库,但从我在您发布的 link 中阅读的文档来看,您似乎在 node.js 中使用了它。在这种情况下,您可以在 node.js
中的函数中使用 arguments
变量来编写您自己的 concat
函数,该函数将 n 个列表作为输入。 arguments
变量本质上是输入到函数中的参数数组。
function myConcat () {
for (var i = 1; i < arguments.length; i++) {
concat(arguments[0], arguments[i]);
}
return arguments[0];
};
但是在这种情况下,您可能不得不这样称呼它:
list1 = myConcat(list1, list2, list3, list4);
具体取决于您连接的内容和您的环境(需要 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]
如果您想连接一个列表列表,您可以使用 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]]);
将 R.unnest
与 R.unapply
结合使用允许您将函数作为可变参数调用:
const unnestAll = R.unapply(R.unnest)
unnestAll([1, 2], [3, 4], [5, 6, 7]) //=> [1, 2, 3, 4, 5, 6, 7]
您可以这样使用flatten
方法:
R.flatten([list1, list2, list3, list4, ])
从技术上讲,您传递的是一个包含所有列表的数组。然后你只需将它们全部压平成一个数组。
如果您的某些列表本身可能包含列表,请不要使用此方法 - 它们也会被展平。