1

I have array of object like below:

pages= [
   {
      "id":1,
      "name":"name1",
      "languages":[
         {
            "id":1,
            "lang":"en"
         },
         {
            "id":2,
            "lang":"de"
         }
      ]
   },
   {
      "id":2,
      "name":"name2",
      "languages":[
         {
            "id":1,
            "lang":"en"
         },
         {
            "id":2,
            "lang":"de"
         }
      ]
   },
   {
      "id":3,
      "name":"name3",
      "languages":[
         {
            "id":1,
            "lang":"en"
         }
      ]
   }
]

And array of languages(these will be set by clicking on checkboxes) is as below:

selectedLanguages=['en'];

Now, I want to filter the main array depending upon the selectedLanguages values. I have tried with below code:

pages.filter(page => {
    var present = false;
    page.languages.map(l => {
        if(selectedLanguages.includes(l.lang)) {
            present = true;
        }
    });
    if(present) {
        return page;
    }
})

Desired output: if selectedLanguages = ['en'] then all items from pages, if de then first 2 elements.

It works but I am curious if I can make it better?

Any suggestions would be helpful :) Thanks.

Pradeepb
  • 2,564
  • 3
  • 25
  • 46

3 Answers3

1

You can use a combination of Array#Filter, Array#find and Array#includes for that :

let pages= [
   {
      "id":1,
      "name":"name1",
      "languages":[
         {
            "id":1,
            "lang":"en"
         },
         {
            "id":2,
            "lang":"de"
         }
      ]
   },
   {
      "id":2,
      "name":"name2",
      "languages":[
         {
            "id":1,
            "lang":"en"
         },
         {
            "id":2,
            "lang":"fr"
         }
      ]
   }
]

let selectedLanguages=['fr'];

let result = pages.filter(e => e.languages.find(l => selectedLanguages.includes(l.lang)));
console.log(result);
Zenoo
  • 12,670
  • 4
  • 45
  • 69
1

Rather than trying to create an intermediate array with .map, it would be better to simply check if some of the languages include a lang matching the selectedLanguages:

const pages=[{"id":1,"name":"name1","languages":[{"id":1,"lang":"en"},{"id":2,"lang":"de"}]},{"id":2,"name":"name2","languages":[{"id":1,"lang":"en"},{"id":2,"lang":"de"}]}]
const selectedLanguages=['en'];
console.log(
  pages.filter(({ languages }) => (
    languages.some(({ lang }) => selectedLanguages.includes(lang))
  ))
)
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
0

You can use filter() with indexOf() check for the selectedLanguages array:

var pages= [
   {
      "id":1,
      "name":"name1",
      "languages":[
         {
            "id":1,
            "lang":"en"
         },
         {
            "id":2,
            "lang":"de"
         }
      ]
   },
   {
      "id":2,
      "name":"name2",
      "languages":[
         {
            "id":1,
            "lang":"en"
         },
         {
            "id":2,
            "lang":"de"
         }
      ]
   },
    {
      "id":3,
      "name":"name3",
      "languages":[
         {
            "id":5,
            "lang":"us"
         },
         {
            "id":6,
            "lang":"de"
         }
      ]
   }
];

var selectedLanguages=['en'];

var res = pages.filter((page) => {
   var languageFound = page.languages.find(language => selectedLanguages.indexOf(language.lang) !== -1);
   if(languageFound){
     return page;
   }
});

console.log(res);
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62