Reputation: 11
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}]
Upvotes: 0
Views: 94
Reputation: 11
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:
Split the searchArray string "John ABC 55" into Array ['John', 'ABC', '55']
searchArrayList = searchArray.split(' ');
JOIN()
method will cause the Person array item into single string : [{"John2", "ABC", 55}] => "John1 ABC 55"
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]
Reduce will result into single boolean array : true
Upvotes: 1
Reputation: 236
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!
Upvotes: 0