admin管理员组文章数量:1336148
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 those tags. For this I am using a js function. It works correctly for the first time but When I push second filter in the function it returns wrong data.
Available Filters are:
Binding
- Paperback
- Hardcover
- Audiobook
- Boxed Set
Category
- Classic Rock
- Pop
- Pop Rock
- Electro Pop
- Soft Rock
- Rock
Language
- German
- English
- French
Author
- Male
- Female
- Male/Female
Here is the JSON and code I am using:
var m = {
"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"
}
]
}
// a function which accepts key which is one of binding,category,language,author.
// the array will be filtered on this key
function getFilteredElement(key, value) {
var bookFilter = [];
m.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.title);
}
});
// returning the array of books
return bookFilter;
}
console.log(getFilteredElement('category', 'rock'))
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 those tags. For this I am using a js function. It works correctly for the first time but When I push second filter in the function it returns wrong data.
Available Filters are:
Binding
- Paperback
- Hardcover
- Audiobook
- Boxed Set
Category
- Classic Rock
- Pop
- Pop Rock
- Electro Pop
- Soft Rock
- Rock
Language
- German
- English
- French
Author
- Male
- Female
- Male/Female
Here is the JSON and code I am using:
var m = {
"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"
}
]
}
// a function which accepts key which is one of binding,category,language,author.
// the array will be filtered on this key
function getFilteredElement(key, value) {
var bookFilter = [];
m.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.title);
}
});
// returning the array of books
return bookFilter;
}
console.log(getFilteredElement('category', 'rock'))
For e.g. When I push category = rock
it returns Book 4, Book 5 and Book 6
but If I push category = rock
and language = french
, the returned result should only be Book 5
but it doesn't return correct results.
Could anyone please help.
Share Improve this question edited Dec 13, 2017 at 11:32 hashtagerrors asked Dec 13, 2017 at 11:17 hashtagerrorshashtagerrors 2394 silver badges22 bronze badges 9- I works to me, I don't know if your are calling the function from different places – David Vicente Commented Dec 13, 2017 at 11:26
-
@David If I push
category = rock
andlanguage = french
, the returned result should only beBook 5
but it doesn't return correct results. – hashtagerrors Commented Dec 13, 2017 at 11:29 - These are my outputs for those calls: [ 'Book 4', 'Book 5', 'Book 6' ] [ 'Book 2', 'Book 5', 'Book 6' ] I think they are right – David Vicente Commented Dec 13, 2017 at 11:38
- btw, JSON is a string. what you have is an array with objects. – Nina Scholz Commented Dec 13, 2017 at 11:38
- Maybe what you want is to bine both filters? – David Vicente Commented Dec 13, 2017 at 11:38
3 Answers
Reset to default 5You 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 mas 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);
本文标签: arraysSearch for multiple filters in JSON using Javascript forEach and indexOfStack Overflow
版权声明:本文标题:arrays - Search for multiple filters in JSON using Javascript forEach and indexOf - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742244862a2439065.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论