【问题标题】:Compare two arrays and return a new array with any items only found in one of the original arrays比较两个数组并返回一个新数组,其中包含仅在原始数组之一中找到的任何项目
【发布时间】:2016-04-22 15:02:41
【问题描述】:

["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub"],

["diorite", "andesite", "grass", "dirt", "dead shrub"] 应该返回 ["pink wool"]

因为“粉色羊毛不存在于第一个数组中,即 arr1。但它返回一个空数组。此代码仅适用于数字数组。但当数组仅包含字符串或带有数字的字符串时,代码不起作用。

function diff(arr1, arr2) {

    var newArray = arr2.concat(arr1);  //first joininng both arrays inn one and storing it in newArray 

    var newestArray = [];

    for (var i=0 ; i<newArray.length ; i++) {  //NOW COMPARING EACH ELEMENT OF  newArray  WITH ARR1 AD ARR2 AND PUSHING NOT SAME VALUES TO newestArray
        if (arr1.indexOf(newArray[i]) == -1) {
            newestArray.push(newArray[i]);

            if (arr2.indexOf(newArray[i]) == -1) {
                newestArray.push(newArray[i]);
            }
        }
    }

    return newestArray.filter(Boolean);   //It is returning an empty arrray but it should return "pink wool"
}

diff(["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub"], ["diorite", "andesite", "grass", "dirt", "dead shrub"]);

【问题讨论】:

标签: javascript arrays filter string-comparison indexof


【解决方案1】:

此解决方案具有用于计数的对象的线性方法。

var array1 = ["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub"],
    array2 = ["diorite", "andesite", "grass", "dirt", "dead shrub"];

function symmetricDifference(setA, setB) {
    var o = {}, result = [];
    function count(i, o) {
        return function (a) {
            o[a] = o[a] || { count: 0, value: a };
            o[a].count += i;
        };
    }

    setA.forEach(count(1, o));
    setB.forEach(count(-1, o));
    Object.keys(o).forEach(function (k) {
        if (o[k].count) {
            o[k].count = Math.abs(o[k].count);
            while (o[k].count--) {
                result.push(o[k].value);
            }
        }
    });
    return result;
}

document.write('<pre>' + JSON.stringify(symmetricDifference(array1, array2), 0, 4) + '</pre>');

【讨论】:

    【解决方案2】:

    对于 ES6,Set 如下。

    function diff(arr1, arr2) {
        var s1 = new Set(arr1);
        var s2 = new Set(arr2);
    
        for (let item of s1) {
            if (s2.has(item)) {
                s2.delete(item);
                s1.delete(item);
            }
        }
    
        return Array.from(s1).concat( Array.from(s2) );
        //return [...s1].concat([...s2]);
    }
    

    【讨论】:

      【解决方案3】:

      非常感谢你们的帮助,但是当有人问像我这样的问题时,我们并不是在为我们的问题寻求全新的解决方案。那将是清晰的复制,我将从中学到什么?我一直在解决我的问题怎么办。我的解决方案可以被纠正,我需要解决那个问题,这样我就不会重复这样的错误,并且可以知道我错在哪里。

      我发现只使用大括号有一个非常愚蠢的错误,这解决了我的整个问题。

      function diff(arr1, arr2) {
      
          var newArray = arr2.concat(arr1);  //first joininng both arrays inn one and storing it in newArray 
      
          var newestArray = [];
      
          for (var i=0 ; i<newArray.length ; i++) {  //NOW COMPARING EACH ELEMENT OF  newArray  WITH ARR1 AD ARR2 AND PUSHING NOT SAME VALUES TO newestArray
              if (arr1.indexOf(newArray[i])===-1) {
                  newestArray.push(newArray[i]);
              }  //Solution to my problem,I put this braces after the next if, because of that next if was not running. 
      
              if (arr2.indexOf(newArray[i])===-1) {
                  newestArray.push(newArray[i]);
              }
          }
      
          return newestArray;   //It is returning an empty arrray but it should return "pink wool"
      }
      
      diff(["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub"], ["diorite", "andesite", "grass", "dirt", "dead shrub"]);
      

      【讨论】:

      • 正确嵌套/缩进/格式化您的代码可以帮助避免此类问题。
      【解决方案4】:

      您可以使用Array.forEach 循环和Array.indexOf 来检查数组。

      我们将最大的数组与最短的数组循环,然后确保您也获得每个数组的唯一值,您可以索引找到的匹配项,然后添加在最短的数组中未找到的项数组。

      'use strict';
      
      var arr1 = ["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub", "alpha"],
        arr2 = ["diorite", "andesite", "grass", "dirt", "dead shrub", "beta"];
      
      function compare(left, right) {
        if (!left || !left.length) {
          return right;
        }
        if (!right || !right.length) {
          return left;
        }
        var i, len, source, target, value, result = [],
          indexes = {};
        // swap to make sure we iterate the longest array
        if (left.length > right.length) {
          source = left;
          target = right;
        } else {
          target = left;
          source = right;
        }
      
        source.forEach(function(item) {
          var index = target.indexOf(item);
          if (index >= 0) {
            indexes[index] = true;
            return;
          }
          result.push(item);
        });
        for (i = 0, len = target.length; i < len; i++) {
          if (!indexes[i]) {
            result.push(target[i]);
          }
        }
      
        return result;
      }
      
      console.log(compare(arr1, arr2));
      console.log(compare(arr2, arr1));

      【讨论】:

        【解决方案5】:

        只是你需要找到两个数组之间的差异:

        let diff = (a, b) => a.filter(x => b.indexOf(x) === -1);
        let fullDiff = (a, b) => diff(a, b).concat(diff(b, a));
        
        
        /*
            var a = ["diorite", "andesite", "grass", "dirt", "pink wool", "dead shrub"]
            var b = ["diorite", "andesite", "grass", "dirt", "dead shrub"]
            fullDiff(a,b) // ["pink wool"]
        */
        

        或者在 ES5 中:

        var diff = function(a, b) {
            return a.filter(function(value) { return b.indexOf(value) === -1; });
        },
        
        fullDiff = function(a, b) {
            return diff(a, b).concat(diff(b, a));
        };
        

        附:如果数组真的很大或者它在系统的性能关键部分,最好使用不太复杂的方法(就 big-O 而言)。

        【讨论】:

          【解决方案6】:
          function diffArray(arr1, arr2) {
            return arr1.concat(arr2).filter(
              item => !arr1.includes(item) || !arr2.includes(item)
            )
          }
          diffArray(["df","sds","sdsd",], ["as","as","as"]);
          

          【讨论】:

          • @RazvanDumitru 是的,我认为是 Razvan
          【解决方案7】:

          这是一个简单的示例,将重复的值替换为“x”并将它们过滤掉:

          function diffArray(arr1, arr2) {
          var newArr = [];
          var result = [];
          var array1 = arr1;
          var array2 = arr2;
          //a nested loop to replace duplicate values with 'x'
          for (var i = 0; i < arr1.length; i++){
            for (var j = 0; j < arr2.length; j++) {
              if (array1[i] == array2[j]){
              array1.splice(i, 1, 'x');
              array2.splice(j, 1, 'x');
                    }
                }
            }
          
          newArr = array1.concat(array2);
          
          //remove the 'x's
          for (var k = 0; k < newArr.length; k++) {
            if (newArr[k] != 'x') {
              result.push(newArr[k]);
                  }
              }
          
            return result;
          }
          
          diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5, 6, 7, 7]);
          

          【讨论】:

            【解决方案8】:

            对我来说更容易!

            function diffArray(arr1, arr2) {
             var newArr = [];
            
              function isIn(value){
                 if (arr2.indexOf(value) === -1){
                    return true;  
                 }
                 arr2.splice(arr2.indexOf(value), 1); 
              }
            
              newArr = arr1.filter(isIn);
            
              return newArr.concat(arr2);
            }
            

            filter 和 indexOf 完成了大部分工作,而 splice 为我们提供了其余未匹配的元素,因此无需检查数组是否比其他数组大!祝你好运!

            【讨论】:

              【解决方案9】:

              我觉得这样比较容易理解

              function diffArray(arr1, arr2) {
              
                  var newArray = [];
              
                  var condition1 =  arr1.forEach(function(x) {
                      if(!arr2[arr2.indexOf(x)]) {
                          newArray.push(x);
                      }
                  });
              
                  var condition2 = arr2.forEach(function(y){
                      if(!arr1[arr1.indexOf(y)]) {
                          newArray.push(y);
                      }
                  });
              
              
                  var compare = arr1.length > arr2.length ? condition1 : condition2;
              
                  return newArray;
              }
              

              【讨论】:

              • 谢谢@fernandosavio
              【解决方案10】:

              https://lodash.com/docs/4.17.4#difference 可以使用 lodash

              使用 _.difference(array, [values]) 找出两个数组值之间的差异

              _.difference([2, 1], [2, 3]); // => [1]

              如果你想检查更多参数的差异,你可以使用 differenceWith 或 DifferenceBy。

              _.differenceWith(数组, [值], [比较器]) https://lodash.com/docs/4.17.4#differenceWith

              .differenceBy(array, [values], [iteratee=.identity]) https://lodash.com/docs/4.17.4#differenceBy

              【讨论】:

                【解决方案11】:

                这是解决这个问题的好方法:

                function diffArray(arr1, arr2) {
                  var newArray = arr1.concat(arr2);
                
                  function find(item) {
                    if (arr1.indexOf(item) === -1 || arr2.indexOf(item) === -1) {
                      return item;
                    }
                  }
                
                  return newArray.filter(find);
                }
                
                diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5, 6, 7, 7]);
                

                【讨论】:

                  【解决方案12】:

                  答案较长,但逻辑很混乱。

                  function diffArray(arr1, arr2) {
                    var newArrUn;
                    // Same, same; but different.
                    if (arr2.length >= arr1.length) {
                      var newArr = [];
                      var newArrY = [];
                      var UnusualElement = [];
                      var UnusualElementY = [];
                      for (var i = 0; i < arr2.length; i++) {
                        newArr[i] = arr1.indexOf(arr2[i]);
                      }
                      for (var t = 0; t < arr1.length; t++) {
                        newArrY[t] = arr2.indexOf(arr1[t]);
                      }
                  
                      for (var j = 0; j < newArr.length; j++) {
                        if (newArr[j] === -1) {
                          UnusualElement[j] = arr2[j];
                        }
                      }
                      for (var e = 0; e < newArrY.length; e++) {
                        if (newArrY[e] === -1) {
                          UnusualElementY[e] = arr1[e];
                        }
                      }
                      return (UnusualElement.filter(Boolean)).concat(UnusualElementY.filter(Boolean));
                  
                    } else {
                      if (arr1.length >= arr2.length) {
                        var newArrX = [];
                        var newArrXX = [];
                        var UnusualElementX = [];
                        var UnusualElementXX = [];
                        for (var b = 0; b < arr1.length; b++) {
                          newArrX[b] = arr2.indexOf(arr1[b]);
                        }
                        for (var u = 0; u < arr2.length; u++) {
                          newArrXX[u] = arr1.indexOf(arr2[u]);
                        }
                        for (var x = 0; x < newArrX.length; x++) {
                          if (newArrX[x] === -1) {
                            UnusualElementX[x] = arr1[x];
                          }
                        }
                        for (var z = 0; z < newArrXX.length; z++) {
                          if (newArrXX[z] === -1) {
                            UnusualElementXX[z] = arr2[z];
                          }
                        }
                        return (UnusualElementX.filter(Boolean)).concat(UnusualElementXX.filter(Boolean));
                      }
                    }
                  }

                  【讨论】:

                    【解决方案13】:
                    function diffArray(arr1, arr2) { 
                        var newArr = []; // Same, same; but different. 
                    
                        for(let i = 0; i< arr1.length;i++) { 
                            if(arr2.indexOf(arr1[i])==-1) { 
                                newArr.push(arr1[i]); 
                            } 
                        } 
                    
                        for(let i = 0; i< arr2.length;i++) { 
                            if(arr1.indexOf(arr2[i])==-1) { 
                                newArr.push(arr2[i]); 
                            } 
                        } 
                        return newArr; 
                    } 
                    diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
                    

                    【讨论】:

                    • 我怀疑这是否有帮助或根本有效。为了说服别人,请解释你的代码是如何工作的以及它为什么有用。
                    猜你喜欢
                    • 1970-01-01
                    • 2020-08-17
                    • 1970-01-01
                    • 2015-07-19
                    • 1970-01-01
                    • 2016-08-06
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-06-17
                    相关资源
                    最近更新 更多