tes rocky tes rocky - 4 months ago 9
Javascript Question

No gettin the right result

I been trying to delete the key of and array of objects if its not the same, and return a new array with objects.

var all = [{banana: 1, rose: 2, mouse: 9, apple: 5}, {banana: 1, rock: 58, car: 19, apple: 5}, {banana: 1, red: 14, clue: 89, apple: 5}];

function differentKeys(arr){
var different_keys = [];
for (var i = 0; i < arr.length; i++) {
var tempObj = {};
for (var key in arr[i]) {
if (!arr[i][key] || arr[i][key] != arr[0][key] && i !== 0) {
tempObj[key] = arr[i][key];
different_keys.push(tempObj);
}
}
}
console.log(different_keys);
}

differentKeys(all);


Result expecting to be:

different_keys = [{rose: 2, mouse: 9}, {rock: 58, car: 19}, {red: 14, clue: 89}];


Getting:

different_keys = [{rock: 58, car: 19}, {red: 14, clue: 89}];

Answer

Your if statement doesn't process the first element because of i !== 0, plus it only compares the other elements against the first, not against each other (but you don't see that because it just so happens that with your sample input the second and third objects don't have any common keys that aren't also in the first object). And it is .push()ing the tempObj inside the for..in when it should do that after the for..in.

You need to nest three loops: an outermost loop to iterate over the input objects as in your current code, a middle loop to iterate over the properties of the current object as per your current code, and then an inner loop to check all the other objects to see if they have that property.

So perhaps a little something like the following.

var all = [{banana: 1, rose: 2, mouse: 9, apple: 5}, {banana: 1, rock: 58, car: 19, apple: 5, cheese: 3}, {banana: 1, cheese: 2, red: 14, clue: 89, apple: 5}];

function differentKeys(arr) {
  var result = [];
  for (var i = 0; i < arr.length; i++) { // process all elements
    var tempObj = {};
    for (var key in arr[i]) { // process keys in current element
      var found = false;
      for (var j = 0; j < arr.length; j++) { // compare against other elements
        if (i !== j && arr[j][key] === arr[i][key]) {
          found = true;
          break;
        }
      }
      if (!found) {
        tempObj[key] = arr[i][key];
      }
    }
    result.push(tempObj);
  }
  return result;
}
console.log(differentKeys(all));

Note: the above assumes that if two objects have properties with the same name but different values (like the cheese property I added to the second and third objects) that you want those included in the results. Note also that I've changed it so the function returns the results rather than logging them (I then the log function's return).

Or here is equivalent logic implemented with a more functional approach - notice how much shorter the function is:

var all = [{banana: 1, rose: 2, mouse: 9, apple: 5}, {banana: 1, rock: 58, car: 19, apple: 5, cheese: 3}, {banana: 1, cheese: 2, red: 14, clue: 89, apple: 5}];

function differentKeys(arr) {
  return arr.map(function(v, i) {
    return Object.keys(v).reduce(function(a, c) {
      if (!arr.some(function(o, j) { return i != j && v[c] === o[c]; }))
        a[c] = v[c];
      return a;
    }, {});
  });
}
console.log(differentKeys(all));

Comments