0

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 :)

0

2 Answers 2

1

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));
Sign up to request clarification or add additional context in comments.

6 Comments

Why use .filter(...).length > 0 instead of .some(...)?
@Barmer Yes thats even better, updated the answer using .some()
Thank you @karthikdivi for your response. it works for year but it does not work for title and people.
@DjSh I have tested for all three cases, you can run and see it here onecompiler.com/javascript/3v2t9b96g
I just ran it on your example and this is the results people: [ [Object], [Object], [Object] ] which shows it does not work
|
0

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)))
    }

4 Comments

would you please help me understand your code. I have provided a codepen. I dont understand how to apply it there
@DjSh I've made a attempt for vue. The basic strategy is to reduce the main array of objects to array of arrays and store it(arr2d). This arr2d will contain list of strings in the same index like [['item','person1','person2',2018],['item2','person3','person4',....]]. This way, you can easily filter everything.
Thank you very much for your time and help. I had to modify your code for it work. Codepen. there was no need for the if statement( bcs of the way you initialized arr2d).
@DjSh I wanted to make arr2d permanent and not to be calculated on each search type in. The way you've initialized it, it'll calculate arr2d again and again from the same publications again and again for each search letter. I want that part of the calculations outside the filteredArray() method if possible. It should be calculated only on new entry of publications.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.