JavaScript,比较不同大小的数组

3

对于两个可能不同大小的数组,如何最好地判断它们是否在尽可能多的情况下相同。

例如:

var a1 = [ 1, 2, 3 ];
var a2 = [ 1, 2 ];
var a3 = [ 1, 3 ];

a1 == a2 => true;
a1 == a3 => false;

我相信这已经被做了数千次,语法也已经被牢记。

为什么第一个是true而第二个是false? - Gumbo
为什么 ala2 是相同的?因为 a2 的内容在 a1 中存在吗? - Fahim Parkar
7个回答

4
这个问题(我只是举例说明 a1 和 a2 -> 我假设您可以根据此创建函数)怎么处理呢?
var min_val = min(a1.length, a2.length);
var equals = true;

for(i = 0; i < min_val; i++)
{
    if(a1[i] != a2[i])
    {
        equals = false;
        break;
    }
}

结果将会被保存在 equals 变量中。如果你想把这个过程封装成一个函数,只需将 a1 和 a2 作为参数传递,并返回 equals 即可。

没错,这样做可以解决问题,但是我认为使用切片等方法可以在不创建函数的情况下完成。 - cc young
1
与切片解决方案不同,这种方法也适用于非标量值,即对象数组。 - georg

3
function compareArraySeq(a1, a2) {
  var i, l = Math.min(a1.length, a2.length); 

  for (i=0; i<l; i++) {
    if (a1[i] !== a2[i]) return false;
  }
  return true;
}

3

[编辑] 根据 Tomalaks 的评论,我认为 JSON 可以提供帮助。

所以,再次展示一个 Array 扩展,它可以做到您想要的功能 [我猜想]:

function comparePartial(arr1,arr2){
  var arr2 = this, l1 = arr1.length, l2 = arr2.length;

  return ( l1<1 || l2<1
            ? false :
              JSON.stringify(arr1.slice(0, l2)) ===
              JSON.stringify(arr2.slice(0, l1))
         );
}
Array.prototype.comparePartial = 
    Array.prototype.comparePartial || comparePartial;

//usage
    var a1 = [ 1, 2, 3 ]
   ,a2 = [ 1, 2 ]
   ,a3 = [ 1, 3 ]
   ,a4 = ['','']
   ,a5 = ['','','']
   ,a6 = []
   ,a7 = ['bla','doh',1]
   ,a8 = ['bla','doh',1,'yeah','really']
   ,a9 = [1,3,5,'doh']
   ,a10= ['1','3','5','doh']
   ,a11= [{a:1,b:2},{c:3,d:4}]
   ,a12= [{a:1,b:2},{c:3,d:4},{e:5,f:6}]

console.log(
  [ a1.comparePartial(a2)
   ,a2.comparePartial(a1)
   ,a1.comparePartial(a3)
   ,a4.comparePartial(a5)
   ,a5.comparePartial(a6)
   ,a1.comparePartial(a6)
   ,a8.comparePartial(a7)
   ,a10.comparePartial(a9)  //=> 'type safe' comparison
   ,a11.comparePartial(a12) //=> can compare arrays of Objects
  ].join(' - ')
); //=> true - true - false - true - false - false - true - false - true

非常聪明,可以不用函数定义来使用这种方法,但是会打太多字了。 - cc young
也许数组扩展是一个好主意? - KooiInc
1
@KooiInc 请查看我对此答案的评论。将数组转换为字符串是不够的。 - Tomalak
@Tomalak:是的。我用JSON变量替换了我的答案。 - KooiInc
@KooiInc 可能不是特别高效,但作为交换,它很简单且适用于嵌套数据。+1 - Tomalak

3
function compareArraySeq(a, b) {
    return a.slice(0, b.length).join(' ') == b.slice(0, a.length).join(' ');
}

太棒了!不需要函数调用!输入开销也不算太大。 - cc young
@ccyoung,对于空字符串数组元素,这种方法会失败,你不应该使用它。 - Tomalak
@bebraw 不,不是这样的。无论您使用什么分隔符,在数组元素包含它时,您的解决方案都会出错。 - Tomalak
@Tomalak 明白了。所以如果需要比较除数字列表之外的其他内容,最好使用其他解决方案。 :) - Juho Vepsäläinen
2
@ccyoung "当星星排成一线"是一种注定失败的编程方式。 - Tomalak
显示剩余6条评论

0
function prefixEqual(a, b) {
    var prefixLength = a.length < b.length ? a.length : b.length;
    for(var i = 0; i < prefixLength; i+=1)
        if( a[i] != b[i] )
            return false;
    return true;
}

0

循环检查一个位置。

我已经做了这个:

var compare = function (a1, a2) {
    var l = Math.min(a1.length, a2.length);
    for (var i = 0; i < l; i++) {
        if (a1[i] !== a2[i]) {
            return false;
        }
    }
    return true;
}

现在你可以像这样比较数组:

var a = [0, 1, 2, 3];
var b = [0, 1, 2];
var c = [0, 1, 3];

compare(a, b); //true
compare(a, c); //false

希望这对你有用 :)
Fiddle链接:http://jsfiddle.net/8zbJj/1/

0
如果您的数组是字符串、数字或布尔值,您可以比较它们的字符串值。
function compareSimpleValues(a,b){
  if(a.length>=b.length)return String(a).indexOf(String(b))===0;
  return String(b).indexOf(String(a))===0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接