简体   繁体   中英

Comparing two arrays in Javascript

I've got two arrays in Javascript which currently look like this, but are updated by HTTP requests (node):

var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]]
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]]

I'm looking to compare these arrays, so that, if there is an array inside y that is not in x, it will be saved to a new array - z . Note that sometimes the order of arrays inside the arrays will change, but I would not like this to affect the result.

If there is an array inside x that is not in y, however, is should not be saved to z .

I read JavaScript array difference and have been able to replicate this, but if the x array is not shown in y , it is printed to z . I am wondering if it is possible for this not to be stored, only the different items in y ?

Use a higher-order function that accepts an array (which changes with each iteration of y ) and returns a new function that operates on each element (nested array) in some . It returns true if the arrays contain the same elements regardless of order.

function matches(outer) {
  return function (el) {
    if (outer.length !== el.length) return false;
    return el.every(function (x) {
      return outer.indexOf(x) > -1;
    });
  }
}

Iterate over y and return a list of arrays that aren't in x .

function finder(x, y) {
  return y.filter(function (el) {
    return !x.some(matches(el));
  });
}

finder(x, y);

DEMO

You can use this function arrayDiff .

It takes two arrays (A and B) and returns an array of all elements that are in the first array and not in the second (A \\ B), with any duplicates removed. Two array elements are equal if their JSON serialization is the same.

var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]];
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]];

var z = arrayDiff(y, x);

// z is [[322,"93829","092","920238"],[924,"9320","8932","4329"]]

// arrayDiff :: [a], [a] -> [a]
function arrayDiff(a1, a2) {
    let a1Set = toStringSet(a1),
        a2Set = toStringSet(a2);

    return Array.from(a1Set)
                .filter(jsonStr => !a2Set.has(jsonStr))
                .map(JSON.parse);

    // toStringSet :: [a] -> Set<String>
    function toStringSet(arr) {
        return new Set(arr.map(JSON.stringify));
    }
}

This should work even if the order in the inner arrays is different.
I'm assuming you will have only numbers and strings in there and you don't expect a strict comparison between them.

var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]];
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]];

// this will do y \ x
var z = arrDiff(y, x);
console.log(z);


function arrDiff(arr1, arr2) {
  var rez = [];

  for (var i = 0; i < arr1.length; i++) {
    if ( ! contains(arr2, arr1[i])) {
      rez.push(arr1[i]);
    }
  }

  return rez;
}

function contains(arr, x) {
  x = x.slice().sort().toString();
  for (var i = 0; i < arr.length; i++) {
    // compare current item with the one we are searching for        
    if (x === arr[i].slice().sort().toString()) {
      return true;
    }
  }

  return false;
}

Try this:

function getArraysDiff(arr1, arr2) {
   var x = arr1.map(function(a) { return a.join("") });
   var y = arr2.map(function(a) { return a.join("") });
   var z = [];

   for ( var i = 0, l = arr1.length; i < l; i++ ) {
      if ( y.indexOf(x[i]) == -1 ) {
        z.push(arr1[i])
      }
   }

   return z;
}

Or this:

x.filter((function(y) {
    return function(x) {
        return y.indexOf(x.join("")) > -1;
    }
}( y.map(function(y) { return y.join("") }) )))

You can use Array.prototype.forEach() , Array.prototype.every() , Array.prototype.map() , Array.prototype.indexOf() , JSON.stringify() , JSON.parse()

var z = [];
y.forEach(function(val, key) {
  var curr = JSON.stringify(val);
  var match = x.every(function(v, k) {
    return JSON.stringify(v) !== curr
  });
  if (match && z.indexOf(curr) == -1) z.push(curr)
});

z = z.map(JSON.parse);

 var x = [ [292, "2349", "902103", "9"], [3289, "93829", "092", "920238"] ]; var y = [ [292, "2349", "902103", "9"], [322, "93829", "092", "920238"], [924, "9320", "8932", "4329"] ]; var z = []; y.forEach(function(val, key) { var curr = JSON.stringify(val); var match = x.every(function(v, k) { return JSON.stringify(v) !== curr }); if (match && z.indexOf(curr) == -1) z.push(curr) }); z = z.map(JSON.parse); console.log(z); document.querySelector("pre").textContent = JSON.stringify(z, null, 2) 
 <pre></pre> 

You have got 2 arrays:

var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]];
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]];

To create the Z array, you need the following function:

function createZ(){
  var i,j,k=0,z=[],p=x;
  for(j=0;j<y.length;j++){
    for(i=0;i<p.length;i++){
      if(y[j][0]===p[i][0] && y[j][1]===p[i][1] && y[j][2]===p[i][2] && y[j][3]===p[i][3]){
        p.splice(i,1); break;
      } else {
        z[k++]=y[j]; console.log((y[j][0]===p[i][0])+" "+i+","+j);
      }
    }
  }
  return z;
}

Note that the createZ() also prints out the i,j of corresponding entry to the console.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM