Reputation: 16202
I have the following data
persons = [
{
"age":20,
"parameter1":94,
"name":"Foobarin"
},
{
"age":33,
"parameter1":49,
"name":"Johan"
}
]
I want to create an advanced live search which recognizes patterns. An examples could be "foo a20 p94" which would get me the first object. a20 - Search where age is 20 p94 - Search where parameter1 is 94 and then if there is any other text which does not have any set prefix then test that against the name value.
All the values (except name which is case-insensitive) is of type integer. I want to limit the prefixes to predefined such as a, p and not age20. The data-sets is around 400.
I've created a basic live search which searches all variables in the object, but now I do not know where to continue. Any ideas?
Upvotes: 1
Views: 898
Reputation: 10138
It's not foolproof but as a first-pass this is what I'd start with, I'll try to talk through it in pseudo.
First declare a propertyMatrix
, a simple object-map which can point "prefixes" to the actual property names which exist within person. The searchPersons
function accepts a single string (query) value and consists of two main parts:
The query string is split on whitespace characters into an array of "tokens". Each token is also an array of exactly 2 length, containing each token name and token value. At this stage it attempts find the predetermined prefix - if no such entry exists the token name: name
is assumed.
A filter is then applied to the persons
array. For each person we iterate over the tokens
array and make an appropriate comparison, if any single check fails we return false (thus excluding the person from the results).
var propertyMatrix = {
'a': 'age',
'p': 'parameter1'
},
searchPersons = function(query){
var tokens = query.split(/\s+/).map(function(t){
t = t.toLowerCase();
var i = t.match(/\d+$/), p;
if(i && i.length) {
p = t.substring(0, t.indexOf(i));
if(p in propertyMatrix)
return [propertyMatrix[p], parseInt(i, 10)];
}
return ['name', t];
}),
result = persons.filter(function(p){
for(var i=0, l=tokens.length; i<l; i++){
var token = tokens[i][0], value = tokens[i][1];
if(!(token in p)) return false;
if(token === 'name'){
if(p.name.toLowerCase().indexOf(value)<0) return false;
} else if(p[token] !== value) return false;
}
return true;
});
return result;
};
Upvotes: 1