Ramda:检查两个数组是否相等

时间:2019-04-09 12:54:44

标签: javascript functional-programming ramda.js

我仍在学习JavaScript的函数式编程,而且我非常喜欢使用Ramda。

我有两个数组。我想检查它们是否具有相同的值,而与顺序无关。我认为可以使用equals完成此操作。但显然

R.equals([1, 2], [2, 1]) // false

有没有一种有效的方法来检查两个数组是否相等?我的数组由对象组成,如果与1

3 个答案:

答案 0 :(得分:4)

我将eqBycountBy一起使用:

您可以使用countBy构建阵列的“配置文件”:

countBy(identity, [1, 2]);
//=> {"1": 1, "2": 1}

countBy(identity, [2, 1]);
//=> {"1": 1, "2": 1}

然后,您可以将两个配置文件与eqBy进行比较:

eqBy(countBy(identity), [1,2], [2,1])
//=> true

答案 1 :(得分:4)

之所以不能这样工作,除了Ramda函数被命名为equals而不是isEqual之外,还在于Array是固有排序的容器。 [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的答案。

答案 2 :(得分:2)

有多种方法可以通过Ramda实现这一目标

一个想到的是

R.length([1,2]) === R.length([2,1]) && R.isEmpty(R.symmetricDifference([1,2], [2,1]))

编辑:使用R.difference而不是R.symmetricDifference无效,因为第一个只返回第一个列表中未包含在第二个列表中的元素列表。

R.difference([1,2], [2,1,3]) // -> []