JavaScript:如何匹配无序数组
我正在尝试找出如何匹配共享相同元素但不一定以相同顺序排列的数组 例如,这两个数组共享同一组元素,即使它们的顺序不同 有没有办法确定两个数组是否包含相同的元素JavaScript:如何匹配无序数组,javascript,Javascript,我正在尝试找出如何匹配共享相同元素但不一定以相同顺序排列的数组 例如,这两个数组共享同一组元素,即使它们的顺序不同 有没有办法确定两个数组是否包含相同的元素 var search1 = ["barry", "beth", "debbie"]; var search2 = ["beth", "barry", "debbie"]; if (search1 == search2) { document.write("We've found a match!"); } else { d
var search1 = ["barry", "beth", "debbie"];
var search2 = ["beth", "barry", "debbie"];
if (search1 == search2) {
document.write("We've found a match!");
} else {
document.write("Nothing matches");
}
我已经在这里运行了一个代码笔:将您的数组馈送到以下函数:
function isArrayEqual(firstArray, secondArray) {
if (firstArray === secondArray) return true;
if (firstArray == null || secondArray == null) return false;
if (firstArray.length != secondArray.length) return false;
// optional - sort the arrays
// firstArray.sort();
// secondArray.sort();
for (var i = 0; i < firstArray.length; ++i) {
if (firstArray[i] !== secondArray[i]) return false;
}
return true;
}
现在你可能在想,我能不能说arrayOne.sort和arrayTwo.sort然后比较arrayOne==arrayTwo?答案是不,在你的情况下你不能。虽然它们的内容可能相同,但通过引用比较,它们不是相同的对象。首先对它们进行排序。其次,如果它们的长度不同,那么它们就不匹配。 然后,迭代一个数组并用b[i]测试a[i],a是第一个数组,b是第二个数组
var search1 = ["barry", "beth", "debbie"],
search2 = ["beth", "barry", "debbie"];
// If length are different, than we have no match.
if ((search1.length != search2.length) || (search1 == null || search2 == null))
document.write("Nothing matches");
var a = search1.sort(),
b = search2.sort(),
areEqual = true;
for (var i = 0; i < a.length; i++) {
// if any two values from the two arrays are different, than we have no match.
if (a[i] != b[i]) {
areEqual = false;
break; // no need to continue
}
}
document.write(areEqual ? "We've found a match!" : "Nothing matches");
可以使用此函数比较两个数组
function getMatch(a, b) {
for ( var i = 0; i < a.length; i++ ) {
for ( var e = 0; e < b.length; e++ ) {
if ( a[i] === b[e] ){
return true;
}
}
}
}
您只需对它们进行排序,然后进行比较
function compareArrayItems(array1, array2){
array1 = array1.sort();
array2 = array2.sort();
return array1.equals(array2);
}
您可以使用中提供的equals函数。其他一些解决方案的问题是,如果它们在for循环中使用for循环,则它们的复杂性为On²。太慢了!您也不需要排序,也不需要太慢 通过使用一个简单的字典,我们可以将其加速到O2n复杂性1。这增加了O2n存储,但这并不重要 JavaScript 改进 如上所述,对于两个看起来相等的数组,上述函数将返回true。例如,[1,1,2,3]和[1,2,2,3]将返回true。要克服这个问题,只需使用字典中的计数器。这是因为!未定义和!0都返回true
1:实际上是+m复杂度,其中n是第一个数组的大小,m是第二个数组的大小。然而,在理论上,如果数组相等,或者差值名义上为n->∞, 因此,可以说它具有O2n复杂性。如果你觉得自己很迂腐,你可以说这是一个复杂的问题。对它们进行排序,然后比较。@ahruss我已经试过了。但是我似乎得到了返回的布尔值false。您不能通过引用进行比较,这就是您在代码中所做的。如果不进行某种循环/排序,即检查每个值,您将无法执行此操作。当你简单地做array1===array2时,它只会告诉你它是否是完全相同的实例,也就是说:如果array1和array2是指向同一个完全相同的数组的引用。显然,如果两者都是具有不同项目顺序的不同数组,那么它们就不是同一个数组,您必须循环遍历这些值,并相互检查以解决这个问题。@ahruss无需对它们进行排序。我在下面写了一个线性复杂度的解决方案。根据算法进行排序的速度较慢。在另一个for循环中通过for循环进行比较更慢。也许您应该在排序之前检查它们的长度,以防止不必要的排序。或null。此外,无需重新排列阵列。订单可能很重要。我在回答中提到了这些。对于[1,2,3]和[1,5]以及第一个元素相等的任何两个数组,这都错误地返回true。它还错误地为[2,1]和[1,2]返回false,根据OP的规范,这是相等的。伙计,这是一个bada**解决方案!很好的思考和使用JSs“字典”@Luxelin我对JS非常陌生,所以请原谅我,但从我对你答案的理解来看,这是一个非常优雅的解决方案!你介意我继续我原来的问题吗?我想使用一个对象,如果arr2匹配该对象中的所有名称,我希望它返回对象名称。如果没有,我希望它跳转到一个else-If语句,该语句返回与所有剩余成员匹配的对象名——如果有意义的话。我根据你的回答在这里创建了另一个代码笔:请原谅for循环。@realph这里有一个。就个人而言,由于布局的原因,我更喜欢小提琴而不是密码笔,但可以使用任何你喜欢的ofc。注意,我将var groups={group:[…]}更改为var groups=[{}]。如果需要使用旧结构,只需更改console.logfindMatchingArrayarr2,groups;第53行至console.logfindMatchingArrayarr2,groups.group@Luxelin伙计,你是摇滚明星!我将尝试阅读一些您现在正在使用的代码,以尝试理解它。谢谢你的评论!我应该在控制台上看到什么吗?@realph别担心!一年前,我完全不懂JavaScript。实际上什么都没有。不过,我们都必须从某个角度出发。改进的关键是练习编写尽可能多的程序。JavaScript一开始可能看起来很奇怪,但在我看来,它是最好的语言。唾手可得地非常强大,特别是当涉及到,这也是。
var isEqual = function (arr1, arr2) {
if (arr1.length !== arr2.length) {
return false; // no point in wasting time if they are of different lengths
} else {
var holder = {}, i = 0, l = arr2.length;
// holder is our dictionary
arr1.forEach(function (d) {
holder[d] = true; // put each item in arr1 into the dictionary
})
for (; i < l; i++) { // run through the second array
if (!(arr2[i] in holder)) return false;
// if it's not in the dictionary, return false
}
return true; // otherwise, return true
}
}
var arr1 = ["barry", "beth", "debbie"],
arr2 = ["beth", "barry", "debbie"];
console.log(isEqual(arr1,arr2));
// returns true
var isReallyEqual = function (arr1, arr2) {
if (arr1.length !== arr2.length) {
return false; // no point in wasting time if they are of different lengths
} else {
var holder = {}, i = 0, l = arr2.length;
// holder is our dictionary
arr1.forEach(function (d) {
holder[d] = (holder[d] || 0) + 1;
// checks whether holder[d] is in the dictionary: holder[d] || 0
// this basically forces a cast to 0 if holder[d] === undefined
// then increments the value
})
for (; i < l; i++) { // run through the second array
if (!holder[arr2[i]]) { // if it's not "in" the dictionary
return false; // return false
// this works because holder[arr2[i]] can be either
// undefined or 0 (or a number > 0)
// if it's not there at all, this will correctly return false
// if it's 0 and there should be another one
// (first array has the element twice, second array has it once)
// it will also return false
} else {
holder[arr2[i]] -= 1; // otherwise decrement the counter
}
}
return true;
// all good, so return true
}
}
var arr1 = [1, 1, 2],
arr2 = [1, 2, 2];
isEqual(arr1, arr2); // returns true
isReallyEqual(arr1, arr2); // returns false;