比较数组(2D和上面也)

时间:2011-06-24 00:20:18

标签: javascript arrays

我开发了这种比较2个(或更多)数组的方法,并返回任何你想要的结果。

这是通过将数组转换为字符串然后比较它们然后转换回结果来完成的。 (也可以用于其他东西)而不是仅仅进行深度迭代和递归来做同样的事情。

示例

var arr1 = [[8,0,3,0,0,7,0,9,0],[0,9,0,0,3,0,0,0,0],[0,0,0,0,0,0,4,0,6],[0,0,0,0,3,9,7,6,0],[9,6,0,5,0,7,0,8,1],[0,7,4,6,8,0,0,0,0],[5,0,1,0,0,0,0,0,0],[0,0,0,0,5,0,0,7,0],[0,6,0,7,0,0,1,0,8]];
var arr2 = [[8,7,3,0,0,7,0,9,0],[0,9,0,0,3,0,0,0,0],[0,0,0,0,0,0,4,0,6],[0,0,0,0,3,9,7,6,0],[9,6,0,5,0,7,0,8,1],[0,6,4,6,8,0,0,0,0],[5,0,1,0,0,0,0,0,0],[0,0,0,0,5,0,3,7,0],[1,6,0,7,0,0,1,0,8]];

arr1 = JSON.stringify( arr1 );
arr2 = JSON.stringify( arr2 );
var temp = ''; // this object will hold the XOR result

console.log( arr1 );
console.log( arr2 );

for( var i=0; i < arr1.length; i++ ){
    if( arr1[i] == '[' || arr1[i] == ']' || arr1[i] == ',' )
        temp += arr1[i];
    else
        temp += arr1[i] == arr2[i] ? 0 : 1;
}

console.log( temp );

您对此方法有何看法?我相信会更好地表现。

2 个答案:

答案 0 :(得分:0)

这是适用于任何类型对象的版本:

var arr1 = [[8,0,3,0,0,7,0,9,0],[0,9,0,0,3,0,0,0,0],[0,0,0,0,0,0,4,0,6],[0,0,0,0,3,9,7,6,0],[9,6,0,5,0,7,0,8,1],[0,7,4,6,8,0,0,0,0],[5,0,1,0,0,0,0,0,0],[0,0,0,0,5,0,0,7,0],[0,6,0,7,0,0,1,0,8]];
var arr2 = [[8,0,3,0,0,7,0,9,0],[0,9,0,0,3,0,0,0,0],[0,0,0,0,0,0,4,0,6],[0,0,0,0,3,9,7,6,0],[9,6,0,5,0,7,0,8,1],[0,7,4,6,8,0,0,0,0],[5,0,1,0,0,0,0,0,0],[0,0,0,0,5,0,0,7,0],[0,6,0,7,0,0,1,0,8]];

alert(isEqual(arr1, arr2));

function isEqual(obj1, obj2) {
    //make sure all keys are the same from obj1 -> obj2
    for (var key in obj1) {
        if (obj1[key] && ! obj2[key]) {
            return false;
        }
    }

    //make sure all keys are the same from obj2 -> obj1
    for (var key in obj2) {
        if (obj2[key] && ! obj1[key]) {
            return false;
        }
    }

    //make sure the key values themselves match
    for (var key in obj1) {
        var left = obj1[key];
        var right = obj2[key];
        if (left instanceof Function) {
            //don't compare these
            continue;
        } 
        if (left instanceof Object || left instanceof Array){
            if (! isEqual(left, right)) {
                return false;
            }
        }
        else if (left != right) {
            return false;
        }
    }

    return true;
}

或者,如果您想列出所有差异的位置,您可以使用以下内容:

var arr1 = [[8,0,3,0,0,7,0,9,0],[0,9,0,0,3,0,0,0,0],[0,0,0,0,0,0,4,0,6],[0,0,0,0,3,9,7,6,0],[9,6,0,5,0,7,0,8,1],[0,7,4,6,8,0,0,0,0],[5,0,1,0,0,0,0,0,0],[0,0,0,0,5,0,0,7,0],[0,6,0,7,0,0,1,0,8]];
var arr2 = [[8,0,3,0,0,7,0,9,0],[0,9,0,0,3,0,0,0,0],[1,0,0,0,1,1,4,0,6],[0,0,0,0,3,9,7,6,0],[9,6,0,5,0,7,0,8,1],[0,7,4,6,8,0,0,0,0],[5,0,1,0,0,0,0,0,0],[0,0,0,0,5,0,0,7,0],[0,6,0,7,0,0,1,0,8]];

alert(listDifferences(arr1, arr2));

function listDifferences(obj1, obj2, deltaList, keyPath) {
    if (! deltaList) {
        deltaList = [];
        keyPath = "";
    }
    //make sure all keys are the same from obj1 -> obj2
    for (var key in obj1) {
        if (obj1[key] && ! obj2[key]) {
            deltaList.push("obj1" + keyPath + "[" + key + "]");
        }
    }

    //make sure all keys are the same from obj2 -> obj1
    for (var key in obj2) {
        if (obj2[key] && ! obj1[key]) {
            deltaList.push("obj2" + keyPath + "[" + key + "]");
        }
    }

    //make sure the key values themselves match
    for (var key in obj1) {
        var left = obj1[key];
        var right = obj2[key];
        if (left instanceof Function) {
            //don't compare these
            continue;
        } 
        if (left instanceof Object || left instanceof Array){
            var startingLength = deltaList.length
            if (listDifferences(left, right, deltaList, keyPath + "[" + key + "]").length > startingLength) {
                deltaList.push("obj1" + keyPath + "[" + key + "]");
            }
        }
        else if (left != right) {
            deltaList.push("obj1" + keyPath + "[" + key + "]");
        }
    }

    return deltaList;
}

答案 1 :(得分:0)

我相信您的方法会以牺牲安全性和可读性为代价来恶化性能。我强烈建议不要在生产中使用此代码,除非:

  • 您知道您的技术实际上确实可以正常工作,即使对于比较具有不同数字的数字(例如101)等边缘情况,或者像{{1}这样的数字不佳的数字也是如此}。测试套件是有序的。
  • 您已经通过基准测试证明,这种方法在几种不同的浏览器上比递归算法快得多。
  • 性能提升(如果有的话)证明了其他人必须做的额外工作才能理解您的代码。
  • 彻底评论,解释您的代码所做的事情,您的比较函数对输入数组做出的假设,为什么您的代码会在给定这些假设的情况下运行,以及您的代码方法实际上比天真的方法更快。

我的直觉告诉我,你的技术效率低于显而易见的(对你来说,也许不对我而言)递归算法。无论如何,除了将值转换为字符串所涉及的开销之外,8.999999998还必须递归。然后,循环遍历结果字符串中的每个字符,而不是循环遍历数量较少的元素。