4

I am with some doubts about iterate into a JS Object and some array functions in JavaScript. Let's say I have these variables:

var json1 = "[{"id": 1, "name":"x"}, {"id": 2, "name":"y"}]";
var json2 = "[{"id": 1, "name":"x"}, {"id": 2, "name":"y"}, {"id": 3, "name":"z"}]";

How can I make a variable with only the IDs in a array

var ids1 = json1.ids (would be 1,2)
var ids2 = json2.ids (would be 1,2,3)

and make another variable only with the IDs that are different

var idsdiff = diff(ids1, ids2) (would be 3)
mplungjan
  • 169,008
  • 28
  • 173
  • 236
2Fast4YouBR
  • 1,012
  • 1
  • 12
  • 22
  • 1
    Your JavaScript objects are incorrect. You have nested quotes - also note that [JSON is not JavaScript Object](http://www.fizerkhan.com/blog/posts/JSON-is-not-Javascript-Object.html) – mplungjan Feb 20 '17 at 18:24

6 Answers6

2

You could use a hash table for the id and make the difference with the value. Then render the result by filtering.

function getId(a) { return a.id; }

var obj1 = JSON.parse('[{"id": 1, "name":"x"}, {"id": 2, "name":"y"}]');
var obj2 = JSON.parse('[{"id": 1, "name":"x"}, {"id": 2, "name":"y"}, {"id": 3, "name":"z"}]');
var ids1 = obj1.map(getId);
var ids2 = obj2.map(getId);
var hash = {};

ids1.forEach(function (a) {
    hash[a] = 1;
});
ids2.forEach(function (a) {
    hash[a] = (hash[a] || 0) - 1;
});

var difference = Object.keys(hash).filter(function (a) { return hash[a]; }).map(Number);
console.log(ids1);
console.log(ids2);
console.log(hash);
console.log(difference);
.as-console-wrapper { max-height: 100% !important; top: 0; }

With lodash, you could use _.xor for a symmetric difference.

var ids1 = [1, 2],
    ids2 = [1, 2, 3];

console.log(_.xor(ids1, ids2));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

var json1 = [{"id":1,"name":"x"}, {"id":2,"name":"y"}],
    json2 = [{"id":1,"name":"x"}, {"id":2,"name":"y"}, {"id":3,"name":"z"}],
    result1 = json1.map(function (a) { return a.id; }),
    result2 = json2.map(function (a) { return a.id; });

var diffs = result2.filter(function (item) { 
    return result1.indexOf(item) < 0;
});

console.log(result1);
console.log(result2);
console.log(diffs);

Note indexOf and filter and map are not available in iE before iE9.

UPDATE: as per @alexandru-Ionutmihai's comment, filter will fail on [1,2,4] and [1,2,3]

This code seems better:

var json1 = [{"id":1,"name":"x"}, {"id":2,"name":"y"}],
        json2 = [{"id":1,"name":"x"}, {"id":2,"name":"y"}, {"id":3,"name":"z"}],
        result1 = json1.map(function (a) { return a.id; }),
        result2 = json2.map(function (a) { return a.id; });

//as per @alexandru-Ionutmihai this is inaccurate for [1,2,4] and [1,2,3]
/*var diffs = result2.filter(function (item) { 
    return result1.indexOf(item) < 0;
});*/

//here's a workaround
function arr_diff(a, b) {
  var i,
    la = a.length,
    lb = b.length,
    res = [];
  if (!la)
    return b;
  else if (!lb)
    return a;
  for (i = 0; i < la; i++) {
    if (b.indexOf(a[i]) === -1)
      res.push(a[i]);
  }
  for (i = 0; i < lb; i++) {
    if (a.indexOf(b[i]) === -1) res.push(b[i]);
  }
  return res;
}

var diffs = arr_diff(result1, result2),
  testDiff = arr_diff([1, 2, 4], [1, 2, 3]);

console.log(result1);
console.log(result2);
console.log(diffs);
console.log(testDiff);

arr_diff credit to @Nomaed's comment on this question's answer.

Community
  • 1
  • 1
xGeo
  • 2,149
  • 2
  • 18
  • 39
  • As @alexandru-Ionutmihai says, this method does not work if you use arrays like `json1 = [1,2,3]`, `json2 = [1,2,4]` – ElChiniNet Feb 20 '17 at 19:13
1

You can use map method in combination with filter method.

var json1 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}];
var json2 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}, {"id": 3, "name":"z"}];
var j1=json1.map((x)=>{return x.id});
var j2=json2.map((x)=>{return x.id});
var diff = j2.filter(function(el){
    return j1.indexOf(el)==-1;
}).concat(j1.filter(function(el){
    return j2.indexOf(el)==-1;
}));
console.log(diff);

Also, this code works if both json arrays contains IDs that are different.

var json1 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}, {"id": 4, "name":"y"}, {"id": 5, "name":"y"}];
var json2 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}, {"id": 3, "name":"z"}];
var j1=json1.map((x)=>{return x.id});
var j2=json2.map((x)=>{return x.id});
var diff = j2.filter(function(el){
    return j1.indexOf(el)==-1;
}).concat(j1.filter(function(el){
    return j2.indexOf(el)==-1;
}));
console.log(diff);
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
1

If those JSONs are not parsed, you need one extra step before:

json1 = JSON.parse(json1);

If not, please use this code:

var json1 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}];
var json2 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}, {"id": 3, "name":"z"}];

// extra steps, if necessary
// json1 = JSON.parse(json1);
// json2 = JSON.parse(json2);

function returnID (item) {
    return item.id;
};

json1 = json1.map(returnID);
json2 = json2.map(returnID);

var diff = json2.filter(function (item) {
    return json1.indexOf(item) < 0;
});

console.log(diff);
ElChiniNet
  • 2,778
  • 2
  • 19
  • 27
michail_w
  • 4,318
  • 4
  • 26
  • 43
0

To get the arrays filled with only the id properties of each object, simple do...

var ids1 = json1.map(x => x.id)
var ids2 = json2.map(x => x.id)

If you are using ES6, or a version transpiler, you can use the spread operator to get the difference between the two like:

var diff = [...id1.filter(x => id2.indexOf(x) == -1), ...id2.filter(x => id1.indexOf(x) == -1)]

var json1 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}];
var json2 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}, {"id": 3, "name":"z"}];

var ids1 = json1.map(x => x.id);
var ids2 = json2.map(x => x.id);

var diff = [...ids1.filter(x => ids2.indexOf(x) == -1), ...ids2.filter(x => ids1.indexOf(x) == -1)];
console.log(diff);
m_callens
  • 6,100
  • 8
  • 32
  • 54
0

Here I let you two functions to get the results that you want:

First function (getIds):

var json1 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}];
var json2 = [{"id": 1, "name":"x"}, {"id": 2, "name":"y"}, {"id": 3, "name":"z"}];

function getIds (array) {
    return array.map(function (obj) {
        return obj.id;
    });
}

console.log(getIds(json1));
console.log(getIds(json2));

Second function (getDiff)

var json1 = [1, 2, 4, 5];
var json2 = [1, 2, 3];

function getDiff (array1, array2) {
    return array1.concat(array2).filter(function (id, index, arr) {
        return arr.indexOf(id) === arr.lastIndexOf(id);
    });
}

console.log(getDiff(json1, json2));
ElChiniNet
  • 2,778
  • 2
  • 19
  • 27