使用lodash来比较数组(没有订单的项目存在)

pQu*_*123 98 javascript arrays lodash

我知道我可以使用循环来做到这一点,但我试图找到一种优雅的方式来做到这一点:

我有两个数组:

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
Run Code Online (Sandbox Code Playgroud)

我想用lodash确认两者是一样的."相同"是指array1中没有包含在array2中的项目.

在检查这些项目之间的相等性方面:

['a', 'b'] == ['b', 'a'] 
Run Code Online (Sandbox Code Playgroud)

要么

['a', 'b'] == ['a', 'b'] 
Run Code Online (Sandbox Code Playgroud)

两者都有效,因为这些字母总是按顺序排列.

提前致谢.

Tro*_*ott 179

如果对外部数组进行排序,则可以使用,_.isEqual()因为内部数组已经排序.

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];
_.isEqual(array1.sort(), array2.sort()); //true
Run Code Online (Sandbox Code Playgroud)

请注意,这.sort()将改变数组.如果这对您来说是个问题,请首先使用(例如).slice()或扩展运算符(...)进行复制.

或者,丹尼尔·布迪克在下面的评论中推荐:

_.isEqual(_.sortBy(array1), _.sortBy(array2))
Run Code Online (Sandbox Code Playgroud)

Lodash sortBy()不会改变阵列.

  • 考虑到array.sort()正在改变原始数组.也许这个可能会更好:var array1 = [['a','b'],['b','c']]; var array2 = [['b','c'],['a','b']]; _.isEqual([... array1] .sort(),[... array2] .sort()); //真正 (5认同)
  • 如果您已经使用lodash,则可以执行_.isEqual(_。sortBy(array1),_sortBy(array2))来防止突变。 (4认同)
  • 添加了两个句子,注意`.sort()`变异并建议首先复制的选项,如果这对用户来说是个问题. (3认同)
  • @DanielBudick 谢谢!我已将其添加到答案中。很棒的建议。 (2认同)

Ste*_*yer 21

您可以xor为此使用破折号

doArraysContainSameElements = _.xor(arr1, arr2).length === 0
Run Code Online (Sandbox Code Playgroud)

如果您认为数组[1,1]与数组[1]不同,则可以这样提高性能:

doArraysContainSameElements = arr1.length === arr2.length === 0 && _.xor(arr1, arr2).length === 0
Run Code Online (Sandbox Code Playgroud)

  • 需要注意的是:这种技术适用于“小”数组,但如果您的数组很大并且大部分不同,那么它可能会带来性能和内存方面的痛苦,因为 _.xor() 将继续超过第一个差异。换句话说,它不会在检测到第一个差异时快速返回。 (3认同)
  • 对于新版本来说这应该是更好的方法 (2认同)

J.K*_*.Ko 7

这里已经有了答案,但这是我的纯 JS 实现。我不确定它是否是最佳的,但它肯定是透明的、可读的和简单的。

// Does array a contain elements of array b?
const union = new Set([...a, ...b]);
const contains = (a, b) => union.size === a.length && union.size === b.length;
// Since order is not important, just data validity.
const isEqualSet = (a, b) => union.contains(a, b) || union.contains(b, a)
Run Code Online (Sandbox Code Playgroud)

的基本原理contains()是,如果a确实包含 的所有元素b,则将它们放入同一个集合中不会改变大小。

例如,如果const a = [1,2,3,4]const b = [1,2],则new Set([...a, ...b]) === {1,2,3,4}。如您所见,结果集具有与 相同的元素a

从那里,为了使它更简洁,我们可以将其归结为以下内容:

const isEqualSet = (a: string[], b: sting[]): boolean => {
  const union = new Set([...a, ...b])
  return union.size === a.length && union.size === b.length;
}
Run Code Online (Sandbox Code Playgroud)

编辑:这不适用于 obj[{a: true}, true, 3] 但可能会比较数组内容,只要它们是原始元素。使用不同顺序的相同值对字符串两个数组进行修复和测试的方法。不适用于对象类型。我建议制作一个通用助手,它根据需要比较的类型调用助手函数。_.isEqual(a. b);从非常棒的 lodash 库中尝试。


Ada*_*uch 6

"相同"是指array1中没有包含在array2中的项目.

你可以使用展平()和差()用于此目的,效果很好,如果你是否有物品不在乎array2是不是array1.听起来你问的是array1是array2的一个子集吗?

var array1 = [['a', 'b'], ['b', 'c']];
var array2 = [['b', 'c'], ['a', 'b']];

function isSubset(source, target) {
    return !_.difference(_.flatten(source), _.flatten(target)).length;
}

isSubset(array1, array2); // ? true
array1.push('d');
isSubset(array1, array2); // ? false
isSubset(array2, array1); // ? true
Run Code Online (Sandbox Code Playgroud)