0

I have two arrays

var a = [{'Id': 1, 'name':'bob', 'age':22}, {'Id': 2, 'name':'alice', 'age':12}, {'Id': 3, 'name':'mike', 'age':13}, {'Id': 4, 'name':'prasad', 'age':25}];
var b = [{'Id': 1, 'name':'bob', 'age':22}, {'Id': 2, 'name':'alice', 'age':12}, {'Id': 3, 'name':'mike', 'age':13}];

I want to compare each element of array a with array b based on ID (Ids are unique always) and want only record which present in array a but not in array b

Here expected output would be

{'Id': 4, 'name':'prasad', 'age':25}

What I have tried so far:

for (var elementA of a) {
    var uniqueElement = true;
    for (var elementB of b) {
         //if condition chekcs elementA.Id and elementB.Id
         //setting values
    }
}

I believe there will be elegant approve to solve this?

Prasad Telkikar
  • 15,207
  • 5
  • 21
  • 44

6 Answers6

1

Try following. Create a Set of Ids of b array and then filter array a based on that.

CASE 1: Use Array.filter in case of more than 1 entry

var a = [{'Id': 1, 'name':'bob', 'age':22}, {'Id': 2, 'name':'alice', 'age':12}, {'Id': 3, 'name':'mike', 'age':13}, {'Id': 4, 'name':'prasad', 'age':25}];
var b = [{'Id': 1, 'name':'bob', 'age':22}, {'Id': 2, 'name':'alice', 'age':12}, {'Id': 3, 'name':'mike', 'age':13}];

var objB = b.reduce((a,c) => a.add(c.Id), new Set());

var result = a.filter(v => !objB.has(v.Id));
console.log(result);

CASE 2: Use Array.find in case of 1 entry

var a = [{'Id': 1, 'name':'bob', 'age':22}, {'Id': 2, 'name':'alice', 'age':12}, {'Id': 3, 'name':'mike', 'age':13}, {'Id': 4, 'name':'prasad', 'age':25}];
var b = [{'Id': 1, 'name':'bob', 'age':22}, {'Id': 2, 'name':'alice', 'age':12}, {'Id': 3, 'name':'mike', 'age':13}];

var objB = b.reduce((a,c) => a.add(c.Id), new Set());

var result = a.find(v => !objB.has(v.Id));
console.log(result);
Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59
1

With ES6:

const idsFromB = b.map(item => item.Id)
const c = a.filter(item => idsFromB.indexOf(item.Id) < 0)
//outputs [{'Id': 4, 'name':'prasad', 'age':25}]
Raphael Aleixo
  • 597
  • 6
  • 18
  • More readable and easy to understand. I tried this as well.. working as expected. but sorry I can accept only one answer... Cheers – Prasad Telkikar Oct 24 '18 at 11:30
0

var a = [{ 'Id': 1, 'name': 'bob', 'age': 22 }, { 'Id': 2, 'name': 'alice', 'age': 12 }, { 'Id': 3, 'name': 'mike', 'age': 13 }, { 'Id': 4, 'name': 'prasad', 'age': 25 }];
var b = [{ 'Id': 1, 'name': 'bob', 'age': 22 }, { 'Id': 2, 'name': 'alice', 'age': 12 }, { 'Id': 3, 'name': 'mike', 'age': 13 }];

const na = [];

a.filter((_a) => {
    let isNotUnique = true;
    for (var elementB of b) {
        if (_a.Id === elementB.Id) {
            isNotUnique = false;
            break;
        }
    }
    
    if (isNotUnique) {
        na.push(_a);
    }
    
});

console.log(na);
philip_nunoo
  • 920
  • 3
  • 10
  • 21
0

This is essentially a set difference problem.

var a = [
  {'Id': 1, 'name':'bob', 'age':22},
  {'Id': 2, 'name':'alice', 'age':12},
  {'Id': 3, 'name':'mike', 'age':13},
  {'Id': 4, 'name':'prasad', 'age':25}
];
var b = [
  {'Id': 1, 'name':'bob', 'age':22},
  {'Id': 2, 'name':'alice', 'age':12},
  {'Id': 3, 'name':'mike', 'age':13}
];

console.log(JSON.stringify(diff(a, b), null, 2));

function diff(a, b) {
  return a.filter(x => !b.some(y => deepCompare(x, y)));
}

// https://stackoverflow.com/a/1144249/1762224
function deepCompare(){var t,e,r,n;function o(t,e){var f;if(isNaN(t)&&isNaN(e)&&"number"==typeof t&&"number"==typeof e)return!0;if(t===e)return!0;if("function"==typeof t&&"function"==typeof e||t instanceof Date&&e instanceof Date||t instanceof RegExp&&e instanceof RegExp||t instanceof String&&e instanceof String||t instanceof Number&&e instanceof Number)return t.toString()===e.toString();if(!(t instanceof Object&&e instanceof Object))return!1;if(t.isPrototypeOf(e)||e.isPrototypeOf(t))return!1;if(t.constructor!==e.constructor)return!1;if(t.prototype!==e.prototype)return!1;if(r.indexOf(t)>-1||n.indexOf(e)>-1)return!1;for(f in e){if(e.hasOwnProperty(f)!==t.hasOwnProperty(f))return!1;if(typeof e[f]!=typeof t[f])return!1}for(f in t){if(e.hasOwnProperty(f)!==t.hasOwnProperty(f))return!1;if(typeof e[f]!=typeof t[f])return!1;switch(typeof t[f]){case"object":case"function":if(r.push(t),n.push(e),!o(t[f],e[f]))return!1;r.pop(),n.pop();break;default:if(t[f]!==e[f])return!1}}return!0}if(arguments.length<1)return!0;for(t=1,e=arguments.length;t<e;t++)if(r=[],n=[],!o(arguments[0],arguments[t]))return!1;return!0}
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
0

Use Array.filter() to filter the first array (if the second Array.some() has an element with the first array Id).

The result of arr2.some() is inverted to include only the ones that are not in arr1.

    let arr1 = [{'Id': 1, 'name':'bob', 'age':22}, {'Id': 2, 'name':'alice', 'age':12}, {'Id': 3, 'name':'mike', 'age':13}, {'Id': 4, 'name':'prasad', 'age':25}];
let arr2 = [{'Id': 1, 'name':'bob', 'age':22}, {'Id': 2, 'name':'alice', 'age':12}, {'Id': 3, 'name':'mike', 'age':13}];
    
let result = arr1.filter(x=>!arr2.some(y=>x.Id===y.Id));
console.log(result)    // output: [{'Id': 4, 'name':'prasad', 'age':25}]
Prasad Telkikar
  • 15,207
  • 5
  • 21
  • 44
-1
var c;

a.forEach((aobj) => {
c = 0;
b.forEach((bobj) => {
if (aobj.Id === bobj.Id) {
  c++;
 }
})
 if (c === 0) console.log(aobj);
})`
Christopher Moore
  • 3,071
  • 4
  • 30
  • 46
Sinane
  • 1,614
  • 2
  • 12
  • 17