Ronald Langeveld
Ronald Langeveld

Reputation: 744

How to filter an array from an array

I have the following two datasets:

// This is based on what user input, usually they will just select 1 or 2.
var selected = ['alpha', 'bravo', 'charlie', 'delta', ...] 

  var list = [
   {
      "properties":{
         "name" : "Example Name",
         "tags":{
            "multi_select":[
               {
                  "name":"alpha"
               },
               {
                  "name":"charlie"
               }
            ]
         }
      }
   },
    ...
   // same same but many more objects with different tags each
]

Yes, it's super nested, but it comes from an API...

Anyway, so what I'm trying to do now is filter() it based on the selected terms, example, If list tags contain "alpha, charlie" and "alpha" is selected, it would display object, but if "alpha and bravo" is selected, the object won't match.

So with fewer it can match, but when it gets narrowed don't it shouldn't match.

I tried the following:

let res = list.filter(hb => hb.properties.Tags.multi_select.some(tag => tag.name.includes(selected)));
console.log(res);

This code is largely from Javascript array.filter by element in children

So I noticed, if I have selected "charlie" it returns the correct objects(s) that contains tag "charlie", but when I select more than 1, eg "charlie" and "alpha" it returns nothing even though there is suppose to be matching objects.

Any suggestions how I could improve the filtering?

Thanks in advance.

Upvotes: 1

Views: 88

Answers (2)

jaybhatt
jaybhatt

Reputation: 547

I think the argument of your includes method here shouldn't be an array here, the check should rather be other way around.

let res = list.filter(hb => hb.properties.tags.multi_select.some(tag => selected.includes(tag.name));

Also, one suggestion - It might be more optimal to use Set instead of Array for this use case maybe, if you want to research a bit.

As to why your code is working when you are only having one item, the reason is that the selected array undergoes a string conversion so ["charlie"] becomes charlie which is returned as true as charlie is your first element in the multiselect array. But when you add another item, it happens like this ["alpha", "charlie"] is casted to "alpha,charlie" which is concatenation of two items, so it would naturally return false.

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386868

You need to check every selected tag agains some name of the filtering object.

let res = list.filter(hb => selected.every(tag =>
    hb.properties.tags.multi_select.some(({ name }) => name === tag)
));

Upvotes: 1

Related Questions