Home > Enterprise >  Vue how to search all properties of array
Vue how to search all properties of array

Time:02-12

In my vue-app I want to add a search component, so that I can search for different topics.

here is an example of the data:

persons: [
   {
    name: 'Mr.X',
    gender: 'Male',
    location: {
      address: 'some streetname',
      zipcode: '12345',
      city: 'Berlin',
      lng: 'longitude',
      lat: 'latitude',
    },
    skills: [
     { label: 'foo' },
     { label: 'bar' },
    ],
  },
 ...etc
]

Then in my component I use a computed value:

computed: {
   filteredList() {
     return this.persons.filter((person) => {
       return person.name.toLowerCase().includes(this.search.toLowerCase())
     })
   },
}

the HTML is:

<input type="text" v-model="search" />

<div v-for="(person, index) in filteredList" :key="index">
    <p>{{ person.name }}</p>
</div>

This of course only searches and returns the name. How can I search on all properties? For example If I search for "Berlin" it should also return the object data.

CodePudding user response:

If the results from your search are dynamically retrieved, I'd recommend adding the filtering capability to the service itself, then pass those filters in the request. This takes the load off of the client and places the responsibility on your database which is much more optimized for such a task.

If it must be entirely client-side, you can generalize the filter you have to perform comparisons on arbitrary properties.

filteredList() {
     const filterObj = {
         'name': 'Mr. X',
         'gender': 'Female'
     };

     return this.persons.filter((person) => {
       // For each of the filters defined in the filter object, determine if
       // the object passes the filter. Only take objects that pass all filters.
       let isMatch = Object.entries(filterObj).map(([key, value]) => {
           if (typeof value === 'string')
               return person[key].toLowerCase().includes(value);
           if (typeof value === 'boolean')
               return person[key] === value;
           // etc.
       }).every(i => i);

       return isMatch;
     })
},

CodePudding user response:

First of all you need to form an array, which contains all your primitive values, and then filter it.

Here is the function flatten() that puts all values from your structure into the flat array

const persons = [
   {
    name: 'Mr.X',
    gender: 'Male',
    location: {
      address: 'some streetname',
      zipcode: '12345',
      city: 'Berlin',
      lng: 'longitude',
      lat: 'latitude',
    },
    skills: [
     { label: 'foo' },
     { label: 'bar' },
    ],
  },
]

const flatten = (input) => {
  if (typeof input === 'object') {
    return (Array.isArray(input) ? input : Object.values(input))
      .reduce((acc, x) => acc.concat(flatten(x)), [])
  } else {
    return [input]
  } 
}

console.log(flatten(persons))
console.log(flatten(persons).includes('Berlin'))
  • Related