我仍在学习 JavaScript 函数式编程,我非常喜欢使用 Ramda。
我有两个数组。我想检查它们是否具有相同的值,与顺序无关。我认为这可以用 equals
来完成。但显然
R.equals([1, 2], [2, 1]) // false
有没有一种有效的方法来检查两个数组是否相等?我的数组由对象组成,并且最多可以容纳 X * 10E4 个值(如果对 1 < X < 10 很重要的话)。
最佳答案
它不能那样工作的原因——除了 Ramda 函数被命名为 equals
的事实之外。而不是 isEqual
—— 数组本质上是有序的容器。 [1, 2]
与 [2, 1]
在本质上不同。
标准的无序容器是Set
。不幸的是,这是基于引用相等性,因此它可能会获得 Ramda 认为相等的项目的多个副本。所以最明显的答案将无法正常工作:
// ** Broken -- do not use **
const eqValues = (a1, a2) => R.equals(new Set(a1), new Set(a2))
console.log(eqValues(
[{x: 1}, {x: 2}],
[{x: 1}, {x: 3}]
)) //=> false
console.log(eqValues(
[{x: 1}, {x: 2}],
[{x: 2}, {x: 1}]
)) //=> true
因为在这种情况下它会因长度检查而失败:
console.log(eqValues(
[{x: 1}, {x: 2}, {x: 2}],
[{x: 2}, {x: 1}]
)) //=> false, but should be true, since {x: 2} is the same as {x: 2}
Ramda 没有暴露其内部的_Set
类型——也许它应该——但是it uses them在这样的功能中 difference
,并通过 symmetricDifference
中的那个.这些是用于测试值相等性有问题的值的适当函数。
所以我的回答与 bug 中的回答类似,但我的措辞略有不同:
const eqValues = compose(isEmpty, symmetricDifference)
console.log(eqValues(
[{x: 1}, {x: 2}],
[{x: 1}, {x: 3}]
)) //=> false
console.log(eqValues(
[{x: 1}, {x: 2}],
[{x: 2}, {x: 1}]
)) //=> true
console.log(eqValues(
[{x: 1}, {x: 2}],
[{x: 2}, {x: 1}, {x: 1}]
)) //=> true
<script src="https://bundle.run/ramda@0.26.1"></script><script>
const {compose, isEmpty, symmetricDifference} = ramda; </script>
但是,如果您需要测试多重性——即 arr1
仅包含 {x: 42}
和 arr2
的两个副本有一个,所以它们不同——那么我会使用 customcommander 的答案。
关于javascript - lambda : Check if two arrays are equal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55593426/