2

I have two arrays, for example:

invoices: [
    {id: 90, Client: 'Bob', paid: false, total: 900},
    {id: 91, Client: 'Sarah', paid: false, total: 400}
]

and:

result: [{km: 200, hours: 20, Person: 'Sarah'}]

The invoices array is a JSON response from a GET and will sometimes be larger than result, so I in this case invoices has Bob while it doesnt exist in result.

How can I get the id of any objects whose Client does not appear as Person in result? I tried to do it with a double for loop but it didn't quite work out.

4 Answers 4

1

By generating an object with keys which are the Person values from result, we can use that to efficiently filter the values in invoices, and then use map to return only the id values of the filtered result:

const invoices =  [
    {id: 90, Client: 'Bob', paid: false, total: 900},
    {id: 91, Client: 'Sarah', paid: false, total: 400}
]

const result =  [{km: 200, hours: 20, Person: 'Sarah'}]

const resindexes = result.reduce((c, o, i) =>
  (c[o.Person] = i, c), {});

ids = invoices.filter(o => resindexes[o.Client] === undefined).map(o => o.id);

console.log(ids);

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

2 Comments

=== undefined? what do you mean
@user3660293 only Person names that are in result will be a property in the resindexes object, so resindexes[o.Client] will be undefined for any Client name which was not in result. This allows us to filter invoices to only return the ones whose Client isn't in result.
1

You can filter the invoices Array, using the result Array as this-argument and check for any Client in that (see MDN for Array.filter). Note, the filter-callback should be a normal function (i.e. not an arrow function) to be able to use the result-Array for thisArg.

console.log( `Id(s) not in result\n`, 
  [ {id: 90, Client: 'Bob', paid: false, total: 900}, 
    {id: 91, Client: 'Sarah', paid: false, total: 400},
    {id: 92, Client: 'Mia', paid: false, total: 200} ]
  .filter( 
    function(v) { return !this.find(n => n.Person === v.Client); }, 
    [{km: 200, hours: 20, Person: 'Sarah'}] // <= thisArg
   )
   .map(v => v.id) // <= fetch the found id's
   .join()
);
.as-console-wrapper { top: 0; max-height: 100% !important; }

3 Comments

Change filter(...) to filter(...).map( (invoice) => invoice.id )
map( (invoice) => invoice.id ) does not exist in the answer
That's why I suggested making the change, which will give you a list of just the ids you want.
0

Using Set and flatMap makes for an expressive, efficient solution. Set consumes an array and lets you check for members in constant time. flatMap lets you filter and map at the same time, in essence.

// Data
const invoices = [
  {id: 90, Client: 'Bob', paid: false, total: 900},
  {id: 91, Client: 'Sarah', paid: false, total: 400}
];
const personsArr = [{km: 200, hours: 20, Person: 'Sarah'}];

// Query
const persons = new Set(personsArr.map(r => r.Person));
const result = invoices.flatMap(i => !persons.has(i.Client) ? i.id : []);
console.log(result);

Comments

0

Or you can do it by make persons Map.

Plus of that attempt is you have access to person data by client name.

Notice I incremented invoices for 1 row for better result view.

// Data enter code here
const invoices = [
    {id: 90, Client: 'Bob', paid: false, total: 900},
    {id: 91, Client: 'Sarah', paid: false, total: 400},
    {id: 92, Client: 'Joe', paid: false, total: 400}
];
const personsArr = [{km: 200, hours: 20, Person: 'Sarah'}];

// Query
const persons = new Map(
    personsArr.map(r =>{ 
        return [r.Person, r]
    }
  )
);
// invoices which do not have results
const orphans = invoices.filter((i)=>!persons.has(i.Client));
// id of invoices which do not have results
const orphansId = orphans.map((o)=>o.id)

console.log(orphansId);

it returns: [ 90, 92 ]

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.