比较两个数组并返回一个新数组,其中包含仅在原始数组之一中找到的任何项目

Posted

技术标签:

【中文标题】比较两个数组并返回一个新数组,其中包含仅在原始数组之一中找到的任何项目【英文标题】: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"]);

【问题讨论】:

它对我来说很好。 你可以参考这个链接。这可能会对您有所帮助。 http://***.com/questions/1187518/javascript-array-difference 缩进/格式化你的代码。 @HamletHakobyan 是的,它会起作用我在下一个 if 语句之后放置大括号的错误。注意到了吗?没有人在这里阅读代码来找出如此愚蠢的错误,他们只是给出了自己的解决方案。 Finding matches between multiple JavaScript Arrays的可能重复 【参考方案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]);

【讨论】:

我怀疑这是否有帮助或根本有效。为了说服别人,请解释你的代码是如何工作的以及它为什么有用。

以上是关于比较两个数组并返回一个新数组,其中包含仅在原始数组之一中找到的任何项目的主要内容,如果未能解决你的问题,请参考以下文章

比较两个对象数组并在新数组中返回匹配值

数组的pop,push,shift,unshift()分别是啥?

Sorted Union

前端实现数组去重,如何高效快捷?

数组去重总结

数组去重总结