I have data in JSON format in which I need to perform search. There are different tags available and when I click on them it searches in JSON and returns the items which has
You could use an object for filters
and take the keys the key to search for and the value as excact value for the string.
Properties with commas are splitted and checked.
function getBooks(filters) {
return array.Books.filter(function (o) {
return Object.keys(filters).every(function (k) {
return o[k].split(',').some(function (v) {
return v === filters[k];
});
});
});
//.map(function (o) {
// return o.title;
//});
}
var array = { Books: [{ title: "Book 1", binding: "paperback", category: "pop", language: "english", author: "male" }, { title: "Book 2", binding: "hardcover", category: "pop rock,electro pop", language: "french", author: "female" }, { title: "Book 3", binding: "audiobook", category: "soft rock", language: "german", author: "male,female" }, { title: "Book 4", binding: "boxed set", category: "rock,classic rock", language: "english", author: "female,male" }, { title: "Book 5", binding: "paperback", category: "electro pop,rock,classic rock", language: "french", author: "male/female" }, { title: "Book 6", binding: "paperback", category: "rock", language: "french", author: "male" }] };
console.log(getBooks({ category: 'rock' }));
console.log(getBooks({ category: 'rock', language: 'french' }));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Use can utilize Array.prototype.filter(), Array.prototype.reduce(), and String.prototype.includes() to create such a filtration system, wherein an array
of filters
consisting of key
value
pairs can progressively be added to in order to refine an array
of books
.
See below for a practical example.
// Books.
const books = [
{
"title": "Book 1",
"binding": "paperback",
"category": "pop",
"language": "english",
"author": "male"
},
{
"title": "Book 2",
"binding": "hardcover",
"category": "pop rock,electro pop",
"language": "french",
"author": "female"
},
{
"title": "Book 3",
"binding": "audiobook",
"category": "soft rock",
"language": "german",
"author": "male,female"
},
{
"title": "Book 4",
"binding": "boxed set",
"category": "rock,classic rock",
"language": "english",
"author": "female,male"
},
{
"title": "Book 5",
"binding": "paperback",
"category": "electro pop,rock,classic rock",
"language": "french",
"author": "male/female"
},
{
"title": "Book 6",
"binding": "paperback",
"category": "rock",
"language": "french",
"author": "male"
}
]
// Query.
const query = (books, filters) => {
// filters = [{key: 'category', value: 'string'}..]
return books.filter((book) => {
// Found?
return filters.reduce((found, filter) => {
if (!(book[filter.key].includes(filter.value))) return false
return found
}, true)
})
}
// Log.
console.log('Category = Rock', query(books, [{key: 'category', value: 'rock'}]))
console.log('Category = Rock + Language = French', query(books, [{key: 'language', value: 'french'}]))
console.log('Paperback', query(books, [{key: 'binding', value: 'paperback'}])) // Paperback.
console.log('Paperback + Male', query(books, [{key: 'binding', value: 'paperback'}, {key: 'author', value: 'male'}])) // Paperback + Male.
console.log('Paperback + Male + Pop', query(books, [{key: 'binding', value: 'paperback'}, {key: 'author', value: 'male'}, {key: 'category', value: 'pop'}])) // Paperback + Male + Pop.
This approach solve your problem:
function applyFilters(books, filters) {
for(let filter of filters) {
var key = filter[0];
var value = filter[1];
books = getFilteredElement(books, key, value);
}
return books.map(book => book.title);
}
// a function which accepts key which is one of binding,category,language,author.
// the array will be filtered on this key
function getFilteredElement(books, key, value) {
var bookFilter = [];
books.forEach(function(item){
var getFilterField = item[key];
// since the value is a string, so splitting it and creating an array
var keyArray = item[key].split(',');
// now checking if the passed value has a presence in the above array
if (keyArray.indexOf(value) !== -1) {
// if present pushed the book name
bookFilter.push(item);
}
});
// returning the array of books
return bookFilter;
}
var filtersToApply = [["category", "rock"], ["language", "french"]];
var bookFilter = applyFilters(m.Books, filtersToApply);
console.log(bookFilter);