1

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

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

Because "pink wool is not present in first array i.e arr1.But it is returning an empty array.This code is working fine with numbers only Array.But when array includes only string or strings with numbers the code does not work.

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"]);
fernandosavio
  • 9,849
  • 4
  • 24
  • 34
Uzma Khan
  • 139
  • 1
  • 3
  • 14
  • It works for me fine. – Hamlet Hakobyan Jan 17 '16 at 11:47
  • You can refer this link. this may help you. [http://stackoverflow.com/questions/1187518/javascript-array-difference](http://stackoverflow.com/questions/1187518/javascript-array-difference) – Makwana Ketan Jan 17 '16 at 11:51
  • Indent/format your code. –  Jan 17 '16 at 18:07
  • @HamletHakobyan Yes it will work I did mistake of putting braces after the next if statement.Notice that? Nobody reads here the code to find out such a silly mistake, they just give there own solution. – Uzma Khan Jan 17 '16 at 18:07
  • Possible duplicate of [Finding matches between multiple JavaScript Arrays](http://stackoverflow.com/questions/11076067/finding-matches-between-multiple-javascript-arrays) – Mark Schultheiss Nov 06 '16 at 21:10
  • Possible duplicate of [JavaScript array difference](http://stackoverflow.com/questions/1187518/javascript-array-difference) – John Hascall Jan 19 '17 at 12:40

16 Answers16

2

This Solution has a linear approach with an object for counting.

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>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

Guys thanks a lot for your help but when a person is asking a question like mine,we are not asking for a brand new solution for our problem.That will be clear cut copying and what will I learn from that? What about all the time I put to solve my problem.My solution can be corrected,I need to solve that thing,so that I don't repeat such mistake and can learn where I was wrong.

I found out there was a very silly mistake of braces only and that solved my whole problem.

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"]);
fernandosavio
  • 9,849
  • 4
  • 24
  • 34
Uzma Khan
  • 139
  • 1
  • 3
  • 14
  • 3
    Just nesting/indenting/formatting your code properly could help to avoid such problems. –  Jan 17 '16 at 18:05
2

For ES6, with Set as following.

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]);
}
zangw
  • 43,869
  • 19
  • 177
  • 214
1

You can check the arrays by using a Array.forEach loop and Array.indexOf.

We loop the largest array against the shortest array and then to make sure you get also the values that are single to each array, you can index which matches you found, and then add the items that weren't found in the shortest array.

'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));
Icepickle
  • 12,689
  • 3
  • 34
  • 48
1

It's just you need to find diff between two arrays:

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"]
*/

Or in 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));
};

P.S. If the arrays is really big or it's in a performance-critical part of the system, it's better to use less complex approach (in terms of big-O).

Microfed
  • 2,832
  • 22
  • 25
1
function diffArray(arr1, arr2) {
  return arr1.concat(arr2).filter(
    item => !arr1.includes(item) || !arr2.includes(item)
  )
}
diffArray(["df","sds","sdsd",], ["as","as","as"]);
AT82
  • 71,416
  • 24
  • 140
  • 167
Sumit Patel
  • 130
  • 11
1

This is a straight-forward example, replacing the duplicate values with 'x' and filtering them out:

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]);
0

To me is much easier!

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 and indexOf makes most of the work, and splice give us the rest of the element not matched so it wont be neccessary to check if an array is bigger than other! Good luck!

MHernandez
  • 31
  • 6
0

I think this is easier to understand

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
  • 9,849
  • 4
  • 24
  • 34
0

You can use lodash for this https://lodash.com/docs/4.17.4#difference

use _.difference(array, [values]) to find the differences between two array values

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

If you want to check differences on more parameters you can use differenceWith or differenceBy.

_.differenceWith(array, [values], [comparator]) https://lodash.com/docs/4.17.4#differenceWith

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

anshu purohit
  • 176
  • 2
  • 10
0

This is a neat way to solve this problem:

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]);
0

Longer answer but logic well broken down.

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));
    }
  }
}
nybre
  • 77
  • 8
0
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]);
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • 1
    I doubt that this helps or works at all. To convince be otherwise please explain how your code works and why it helps. – Yunnosch Jan 03 '20 at 23:53
0

THIS IS MY SOLUTION FOR THE ABOVE MENTIONED PROBLEM

function diffArray(arr1, arr2) { let newArray = arr1.concat(arr2) return newArray.filter(item => !(arr1.includes(item) && arr2.includes(item))) }

0

function diffArray(arr1, arr2) {
  const newArr = [];
  for (let item of arr1){if (arr2.indexOf(item)==-1) newArr.push(item);}
  for (let item of arr2){if (arr1.indexOf(item)==-1) newArr.push(item);}
  return newArr;
}

diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
bmd
  • 1
0

Tty this:

function diffArray(arr1, arr2) {
  const newArr = arr1.concat(arr2);
  return newArr.filter( (e) => {
    return arr1.indexOf(e) === -1 || arr2.indexOf(e) === -1 ? e : null;
  });
}
diffArray([1, 2, 3, 5], [1, 2, 3, 4, 5]);
mkamal
  • 199
  • 2
  • 6