Alex
Alex

Reputation: 35881

Client-side full-text search on array of objects

I have the following example JavaScript array of objects and need to enable users to search on it using words/phrases, returning the objects:

var items = [];
var obj = {
    index: 1,
    content: "This is a sample text to search."
};
items.push(obj);
obj = {
    index: 2,
    content: "Here's another sample text to search."
};
items.push(obj);

It's probably efficient to use jQuery's $.grep to perform the search, such as this for a single word:

var keyword = "Here";
var results = $.grep(items, function (e) { 
    return e.content.indexOf(keyword) != -1; 
});

However, how do you search for a phrase in the content field of the objects? For example, searching for the phrase another text won't work using indexOf, because the two words aren't next to each other. What's an efficient way to perform this search in jQuery?

Upvotes: 9

Views: 12758

Answers (2)

Andy
Andy

Reputation: 63587

You can use vanilla JS if you're stuck. It does use filter and every which won't work in older browsers, but there are polyfills available.

var items = [];

var obj = {
  index: 1,
  content: "This is a sample text to search."
};

items.push(obj);

obj = {
  index: 2,
  content: "Here's another sample text to search."
};

items.push(obj);

function find(items, text) {
  text = text.split(' ');
  return items.filter(item => {
    return text.every(el => {
      return item.content.includes(el);
    });
  });
}

console.log(find(items, 'text')) // both objects
console.log(find(items, 'another')) // object 2
console.log(find(items, 'another text')) // object 2
console.log(find(items, 'is text')) // object 1

(Edit: updated to use includes, and a slightly shorter arrow function syntax).

Upvotes: 19

Rune FS
Rune FS

Reputation: 21752

if you use query-js you can do this like so

var words = phrase.split(' ');
items.where(function(e){
           return words.aggregate(function(state, w){ 
                    return state && e.content.indexOf(w) >= 0;
                  });
},true);

if it should just match at least one change the && to || and true to false

Upvotes: 1

Related Questions