Solution 1 :

    searchArrayList = searchArray.split(' ');

    filteredArray = person.filter(function (item) {
                                let row = [item.fname != null ? item.fname.toLowerCase() : '',
                                    item.lName != null ? item.lName.toLowerCase() : '',
                                    item.age != null ? item.age.toLowerCase() : ''].join();
            
                                let result = searchArrayList.map(function (part) {
                                    if (part === '') return true
                                    return row.indexOf(part.toLowerCase()) !== -1
                                })
                                
                                return result.reduce(function (x, y) {
                                    return x&y
                                }, true)
                            })

EXPLAINATION:

  1. Split the searchArray string “John ABC 55” into Array ['John', 'ABC', '55']

    searchArrayList = searchArray.split(' ');
    
  2. JOIN() method will cause the Person array item into single string : [{"John2", "ABC", 55}] => "John1 ABC 55"

  3. Map the search result into boolean Array :

    ["John1 ABC 55"].indexOf("John") => 'true',
    ["John1 ABC 55"].indexOf("ABC") => 'true',
    ["John1 ABC 55"].indexOf("55") => 'true'
    

    Map result => [true, true, true]

  4. Reduce will result into single boolean array : true

Solution 2 :

Assuming query’s format won’t change, this is how I’d do it:


function filterPerson(arr, query) {
   let [fname, lName, age] = query.split(" ").filter(function(chunk) {
      return chunk.trim().length > 0;
   };
   age = age ? +age : null; //converts age to number

   if(!fname) return [];

   arr = arr.filter(function(person) {
      return person.fname.startsWith(fname);
   });

   if(!lName) return arr;

   arr = arr.filter(function(person) {
      return person.lName.startsWith(lName);
   });

   if(!age) return arr;

   arr = arr.filter(function(person) {
      return person.age === age;
   });

   return arr;
}

It would be possible to do it in a single filter function, but then you’d have to check whether first name, last name, and age is set every time you’d filter the array. This way you check the query only once and filter an already filtered query.

Alternatively, you could create a filtering function for each use case e.g. when there is one parameter, two, three, or more parameters.

Or you could reorder the filtering sequence to remove as many entries as possible as early as possible.

Good luck!

Problem :

I’ve implemented a code which will filter the Array of items using the Keywords in the Search tab.

As we enter/delete the keywords entered in the Search tab the Array gets filtered in real time and displayed on the screen.

“Person” Array needs to be filtered:

var person = [{fname : "John1", lName: "ABC", age: 46},
{fname : "John2", lName: "ABC", age: 55},
{fname : "John3", lName: "XYZ", age: 96}];

“Search Array” :

values entered for in searchArray = John ABC 55;

“OUTPUT” :

[{fname : "John2", lName: "ABC", age: 55}]

Comments

Comment posted by How to create a minimal reproducible example

How to create a minimal reproducible example

Comment posted by Andrew Paul

What’s the question?

Comment posted by Heretic Monkey

So what happens if the user enters

Comment posted by Deepi

@HereticMonkey – partial matching is also allowed.

Comment posted by Deepi

@AndrewPaul – if we add “John” -> all 3 rows filtered, After “John ABC” entered -> first 2 rows got filtered , “John ABC 55” -> will filter out 2nd row

By