Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering array of objects by searching nested object properties

I have an array of objects that I want to filter by comparing a nested property to a search term.

For example:

 var array = [
      {category: 'Business'
       users: [
                {name: 'Sally'
                 tags: [{tag: 'accounting'}, {tag: 'marketing'},...]
                },
                {name: 'Bob'
                 tags: [{tag: 'sales'}, {tag: 'accounting'},...]
                }...
              ]
       },
       {category: 'Heritage'
        users: [
                 {name: 'Linda'
                  tags: [{tag: 'Italy'}, {tag: 'Macedonia'},...]
                 },
                 {name: 'George'
                  tags: [{tag: 'South Africa'}, {tag: 'Chile'},...]
                 },...
               ]
       },...
    [

Essentially I want to filter the base array of objects by a search terms that include characters from the tag property string in the nested objects 2 arrays down.

So a search for 'market' would result in

[
  {category: 'Business'
   users: [
            {name: 'Sally'
             tags: [{tag: 'accounting'}, {tag: 'marketing'},...]
            },
            {name: 'Bob'
             tags: [{tag: 'sales'}, {tag: 'accounting'},...]
            }...
          ]
   }
]

Thank you.

like image 561
slotdp02 Avatar asked Aug 08 '17 17:08

slotdp02


2 Answers

You could use Array#filter with looking into the nested arrays by using Array#some.

If the tag is found in a nested array, then iteration stops and the result is given back to the filter callback.

var array = [{ category: 'Business', users: [{ name: 'Sally', tags: [{ tag: 'accounting' }, { tag: 'marketing' }] }, { name: 'Bob', tags: [{ tag: 'sales' }, { tag: 'accounting' }] }] }, { category: 'Heritage', users: [{ name: 'Linda', tags: [{ tag: 'Italy' }, { tag: 'Macedonia' }] }, { name: 'George', tags: [{ tag: 'South Africa' }, { tag: 'Chile' }] }] }],
    tag = 'marketing',
    result = array.filter(a => a.users.some(u => u.tags.some(t => t.tag.includes(tag))));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 74
Nina Scholz Avatar answered Nov 12 '22 04:11

Nina Scholz


The solution using Array.prototype.some() function:

var arr = [{ category: 'Business', users: [{ name: 'Sally', tags: [{ tag: 'accounting' }, { tag: 'marketing' }] }, { name: 'Bob', tags: [{ tag: 'sales' }, { tag: 'accounting' }] }] }, { category: 'Heritage', users: [{ name: 'Linda', tags: [{ tag: 'Italy' }, { tag: 'Macedonia' }] }, { name: 'George', tags: [{ tag: 'South Africa' }, { tag: 'Chile' }] }] }], 
    search_key = 'market',
    result = [];
    
arr.forEach(function(o){
    if (o.users.some(function(v){
        return v.tags.some(function(i){ return i.tag.indexOf(search_key) !== -1; });
    })) {
        result.push(o);
    }
});

console.log(result);
like image 39
RomanPerekhrest Avatar answered Nov 12 '22 02:11

RomanPerekhrest