【问题标题】:javascript compare two array find differencejavascript比较两个数组找到差异
【发布时间】:2016-07-01 20:15:51
【问题描述】:

我有两个数组,可以是整数数组、字符串数组甚至是对象数组,出于演示目的,我将使用整数数组。

array1:        array2:
 0              99
 1              1             
 101            5
 2              100
 100            97  
 5              101   
 4              4  

我想让一个函数返回包含两个数组之间差异的所有信息。 结果是:

 0     --                 {match:false,leftIndex:0             }
 --    99                 {match:false:            rightIndex:0}
 1     1                  {match:true: leftIndex:1,rightIndex:1}
 --    5                  {match:false:            rightIndex:2}
 --    100                {match:false:            rightIndex:3}
 --    97                 {match:false:            rightIndex:4}
 101   101                {match:false:leftIndex:2,rightIndex:5}
 2     --                 {match:false:leftIndex:3             }
 100   --                 {match:false:leftIndex:4             }
 5     --                 {match:false:leftIndex:5             }
 4     4                  {match:false:leftIndex:6,rightIndex:6}

解决此问题的最佳方法是什么? 我打算使用这个函数来显示这两个数组的并排视图,使用 angularJS 指令方法。这行得通吗?

【问题讨论】:

标签: javascript arrays angularjs angularjs-directive compare


【解决方案1】:

如果rightIndexleftIndex的增量小于零,我建议使用Map作为键和索引作为匹配检查的值。

在这种情况下,找到一个匹配的项目,如果右侧的其他一些值丢失,它们将被拾取。

对于最后一部分,array2 的可能剩余部分也被推送。

0   1   2   4   5  97  99 100 101   values
0   1   3   6   5   -   -   4   2   leftIndex
-   1   -   6   2   4   0   3   5   rightIndex
-   0   -   0  -3   -   -  -1   3   delta: p2 - p1
    *       *                   *   relevant only delta >= 0

var array1 = [0,     1,             101, 2, 100, 5, 4],
    array2 = [   99, 1, 5, 100, 97, 101,            4],
    map = new Map,
    j = 0,
    result = [];

array2.forEach(map.set.bind(map));

array1.forEach(function (a, i) {
    if (map.has(a) && map.get(a) >= i) {
        while (j < map.get(a)) {
            result.push({ value: array2[j], match: false, rightIndex: j });
            j++;
        }
        result.push({ value: a, match: true, leftIndex: i, rightIndex: j });
        j++;
        return;
    }
    result.push({ value: a, match: false, leftIndex: i });
});

while (j < array2.length) {
    result.push({ value: array2[j], match: false, rightIndex: j });
    j++;
}

console.log(result);

【讨论】:

    【解决方案2】:

    如果你可以使用最后的 ES6 特性,我会选择这样的:

    function areArrayEqual(array1, array2) {
        // Based on http://stackoverflow.com/a/14853974/2586392
        if (array1.length !== array2.length) return false;
    
        for (var i = 0, l=array1.length; i < l; i++) {
          if (!areArrayEqual(array1[i], array2[i]) return false;       
          else if (array1[i] != array2[i]) return false;   
        }       
    
        return true;
    })
    
    var result = [];
    array1.forEach((value, i) => {
      let j = array2.findIndex(x => {
        if (typeof value !== typeof x) return false;
        if (typeof value === 'object') return areArrayEquals(Object.values(x), Object.values(value));
        if (typeof value === 'array') return areArrayEquals(x, value);
        return x === value;
      });
    
      result.push([value, j === -1 ? '---' : value , {
        match: !!(j + 1),
        leftIndex: i,
        rightIndex: j === -1 ? '---' : j
      }]);
    
      if (j !== -1) {
        delete array2[j];
      }
    });
    
    array2.forEach((value, i) => {
      result.push(['---', value, {match: false, leftIndex: '---', rightIndex: i}]);
    });
    

    否则你仍然可以使用类似的东西,但你需要 polyfill Object.values 可能还有 forEach

    【讨论】:

    • ES6 功能在哪里?
    • @mortezaT Array.findIndex() 是 ES6,Object.values() 是 ES7(我在这方面不好,虽然我也是 ES6)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多