0

I have two JS objects:

var first = [{name: "Sam", group: "test"}, {name: "John", group: "it"}];
var second = [{name: "John", group: "it"}, {name: "Tim", group: "hr"}];
    
for (var k = 0; k < first.length; k++) {
    if (first.indexOf(second[k]) == -1) {
        console.log('found');
    }
}

I am trying to filter out a value that is present at first, but missing at second. How can I do that?

Ideal return value: {name: "Sam", group: "test"}

Tried many things, nothing works at the moment. For example:

1
  • Not clear what you're asking for. Are you trying to filter out based on the value of a particular property? For example, in your second array, none of the objects share any common values. Commented Jun 29, 2018 at 21:27

3 Answers 3

0

Using Array.filter, we can return items that pass a condition. In this case, the condition is "not in the second list", which we can express with Array.some.

function getItemsOnlyInFirst(first, second) {
  return first.filter(
    item =>
      !second.some(
        compareItem =>
          item.name === compareItem.name && item.group === compareItem.group
      )
  );
}

let first = [{ name: "Sam", group: "test" }, { name: "John", group: "it" }];
let second = [{ name: "John", group: "it" }, { name: "Tim", group: "hr" }];

getItemsOnlyInFirst(first, second); // {name: "Sam", group: "test"}
Sign up to request clarification or add additional context in comments.

Comments

0

The problem is you cannot compare two objects with the == operator:

var obj1 = {test: 1}
var obj2 = {test: 1}

console.log(obj1 == obj2) // false

An easy solution is to convert the objects into the JSON format.

This works because you can compare strings:

var obj1 = JSON.stringify({test: 1})
var obj2 = JSON.stringify({test: 1})

console.log(obj1 == obj2) // true

Solution using JSON.stringify:

var first  = [{name: "Sam", group: "test"}, {name: "John", group: "it"}];
var second = [{name: "John", group: "it"} , {name: "Tim", group: "hr"}];

// Convert the objects to JSON
var second_str = second.map(JSON.stringify)

var filtered = first.filter(function(elem) {
    return second_str.indexOf(JSON.stringify(elem)) == -1
})

console.log(filtered)

Comments

0

I understand they both share same interface? For complex objects you could use lodash with eg: _.differenceBy function, but here the case is simple (still, approach is quite generic, does not depends on keys inside objects, but they need to be in flat structure [no recursion])

let isOnlyInFirst = first.filter(el => {
    return !second.some(z => {
        const el_keys = Object.keys(el)
        const z__keys = Object.keys(z)
        let flag = true
        for (const key of el_keys) {
            if (!z.hasOwnProperty(key) || z[key] != el[key]) flag = false
        }
        if (el_keys.length === z__keys.length && flag)
            return true
        return false
    })
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.