0

Try to avoid using any library as I just need a simple script. I want to get non existing record from existing array.

input = [{name: 'james'}, {name: 'jane'}]

existing = [{name: 'james'}]

//do something

expected input to become [{name: 'jane'}]

I tried this

let input = [{
      name: 'yahoo.com',
    },{
      name: 'google.my',
    }]

    existing = (existing || []).map(o => ({name: o.name})) //clean up data from backend [{name:'google.my'}]


    input = (input || []).map(o => o.name) //just in case input has more property in the future

    input = existing.filter(o => !o.name.includes(input))

    console.log(input)

Somehow I still don't get what I want (expect input to be [{name: 'yahoo.com'}], what is missing? I couldn't spot it.

4
  • {name: 'james', name: 'jane'} is not a valid object Commented Mar 25, 2018 at 10:05
  • please add the wanted result as well. Commented Mar 25, 2018 at 10:07
  • @Eddie fixed the typo, thanks Commented Mar 25, 2018 at 10:09
  • @NinaScholz filter input base on existing, modified my question and added expected result. Commented Mar 25, 2018 at 10:09

5 Answers 5

1

You could filter with a lookup with find.

var input = [{ name: 'james' }, { name: 'jane' }],
    existing = [{ name: 'james' }],
    result = input.filter(({ name }) => !existing.find(o => o.name === name));
    
console.log(result);

Sign up to request clarification or add additional context in comments.

Comments

1

Array.prototype.filter, Array.prototype.map, and Set can be combined using a closure to detect missing elements between arrays of objects using keys.

See below for a practical example.

// Input.
const input = [{name: 'james'}, {name: 'jane'}]

// Existing.
const existing = [{name: 'james'}]

// Missing (B elements from A).
const missing = (A, B) => (s => A.filter(({name}) => !s.has(name)))(new Set(B.map(({name}) => name)))

// Output.
const output = missing(input, existing)

// Proof.
console.log(output)

1 Comment

All good mate. Array.prototype.find() is definitely simpler to read. Set.has() is just more efficient at scale. See the comments of this answer for more info.
0

You can use filter and find

let input = [{name: 'james'}, {name: 'jane'}];
let existing = [{name: 'james'}];

let result = input.filter(v => !existing.find(o => o.name == v.name));


console.log(result);

Comments

0

You can use a combination of two Array#filter.

The first one is looping through your input array, while the second one loops through your existing array to check if each input value is contained inside existing.

let input = [{name: 'james'}, {name: 'jane'}];
let existing = [{name: 'james'}];

let res = input.filter(a => !existing.filter(b => b.name == a.name).length);
console.log(res);

Comments

-1

First, don't reuse variable names, it's confusing (you have two separate things called input.

Second, don't do unnecessary loops. Do a filter right out of the gate and then map to get an array of names (or skip the map altogether if you don't really need it)

let input = [
    {
        name: 'yahoo.com'
    },
    {
      name: 'google.my'
    }
]

    //all names in existing that are also in input
    (existing || [])
         //I used some instead of includes
        .filter(o => !(input || []).some(i => i.name == o.name))
        .map(o => o.name);

MDN Array.prototype.some

1 Comment

Author wants retrieve alla names in input that are not in existing

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.