Cannot return specific items in deep object

Viewed 70

I have two arrays of objects, defined as following:

contacts array:

[
   { id: "1", name: "test"},
   { id: "2", name: "foo" },
   { id: "3", name: "june"},
   { id: "4", name: "may" }
]

filtered_contacts array:

[
   {
       id: "1", 
       options: [
           { option_id: "1", contact_linked_id: "2" },
           { option_id: "2", contact_linked_id: "4" },
       ]
   },
   {
       id: "2", 
       options: [
           { option_id: "3", contact_linked_id: "1" },
       ]
   },
]

I need to extract the contacts which are included in filtered_contacts with the contact_linked_id field, for doing so I wrote the following code:

 var c = contacts.map(c => filtered_contacts.find(x => x.options.map(z => z.contact_linked_id == c.id)));

but the result is completely wrong, I get a lot of copies of the first contact : test.

2 Answers

You could take a Set and collect the contacts and then filter the array.

var contacts = [{ id: "1", name: "test" }, { id: "2", name: "foo" }, { id: "3", name: "june" }, { id: "4", name: "may" }],
    filtered_contacts = [{ id: "1", options: [{ option_id: "1", contact_linked_id: "2" }, { option_id: "2", contact_linked_id: "4" }] }, { id: "2", options: [{ option_id: "3", contact_linked_id: "1" }] }],
    cSet = filtered_contacts.reduce(
        (s, { options }) => options.reduce(
            (t, { contact_linked_id: id }) => t.add(id),
            s
        ),
        new Set
    ),
    result = contacts.filter(({ id }) => cSet.has(id));
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

You can use Set and filter it like this:

const contacts=[{id:"1",name:"test"},{id:"2",name:"foo"},{id:"3",name:"june"},{id:"4",name:"may"}]
     ,filtered_contacts=[{id:"1",options:[{option_id:"1",contact_linked_id:"2"},{option_id:"2",contact_linked_id:"4"},]},{id:"2",options:[{option_id:"3",contact_linked_id:"1"},]},]

/*
  > Get array of options 
  > flatten them 
  > get array of contact_linked_id
  > Get unique ids
*/
,filteredIds = new Set(filtered_contacts.flatMap(a => a.options)
                                        .map(a => a.contact_linked_id));

console.log(contacts.filter(a => filteredIds.has(a.id)))

If flatMap isn't supported in your browser yet, use:

filteredIds = new Set([].concat(...filtered_contacts.map(a => a.options))
                         .map(a => a.contact_linked_id));
Related