简体   繁体   中英

filter nested array of objects based on object values Javascript ES6

I am trying to filter below array of objects against search variable which is a string. So, user can search based on title, year or name of people

array = [{
    "title": "Test",
    "year": 2018,
    "people": [
      {
        "name": "person1"
      },
      {
        "name": "person2"
      }],
  },
  {
    "title": "Test2",
    "year": 2018,
    "people": [
      {
        "name": "person3"
      },
      {
        "name": "person4"
      },
      {
        "name": "person5"
      }],
   },...]

I have written the below function which works fine for title and year but I could not figure out how to search the people array inside the function. I know how to do it without ES6 but I prefer ES6 which is still confusing to me:

filteredArray() {
            let search = this.search.toLowerCase();
            return this.array.filter(function (item) {
                    return Object.values(item).some(val =>
                        String(val).toLowerCase().includes(search));
            })
        },

this.search is the v-model that holds the value user types in. Here is the Codepen

I appreciate your help:)

Following code helps your usecase

   var searchString = 'person5';

   let result = array.filter(ele => 
    ele.title.includes(searchString)
    || `${ele.year}`.includes(searchString)
    || ele.people.some(pele => pele.name.includes(searchString))
   )
   console.log(JSON.stringify(result));

Create a Map/hash of search strings to easily search:

 const array = [{ "title": "Test", "year": 2018, "people": [ { "name": "person1" }, { "name": "person2" }], }, { "title": "Test2", "year": 2018, "people": [ { "name": "person3" }, { "name": "person4" }, { "name": "person5" }], }]; let map = array.reduce((map,item,i)=>{ let values = Object.values(item); let persons = values.pop().map(e=>e.name); [...values,...persons].forEach(e=>map.set(String(e).toLowerCase(),i)) return map; },new Map()); //console.log(...map); ['person1','person3','Test2'].forEach(e=>console.log({[e]:array[map.get(String(e).toLowerCase())]}))

For Vue, try

filteredArray() {
    let search = this.search.toLowerCase();
    let arr2d = this.arr2d;
    if(typeof arr2d ==="undefined"){
     arr2d = this.array.reduce((arr,item)=>{
      let values = Object.values(item);
      let persons = values.pop().map(e=>e.name);
      arr.push([...values,...persons]);
      return arr;
     },[]);
    }
    return this.array.filter((item,i)=>arr2d[i].some(el=>
        String(el).toLowerCase().includes(search)))
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM