我有JSON格式的数据,我需要在其中执行搜索。有不同的标签可用,当我点击它们时,它会搜索JSON并返回包含这些标签的项目。为此,我使用的是js函数。它第一次正常工作,但是当我在函数中推送第二个过滤器时,它会返回错误的数据。
可用的过滤器是:
装订
分类
语言
作者
这是我正在使用的JSON和代码:
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'))
例如当我按category = rock
时,它会返回Book 4, Book 5 and Book 6
,但如果我按category = rock
和language = french
,则返回的结果应该只是{ {1}}但它没有返回正确的结果。
有人可以帮忙。
答案 0 :(得分:4)
您可以使用filters
的对象,并使用键搜索键,并将值作为字符串的精确值。
分割并检查带逗号的属性。
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; }
答案 1 :(得分:2)
使用可以利用Array.prototype.filter()
,Array.prototype.reduce()
和String.prototype.includes()
来创建这样的过滤系统,其中array
filters
由key
组成可以逐步添加value
个对,以优化array
books
。
请参阅下面的实例。
// 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.
答案 2 :(得分:0)
这种方法可以解决您的问题:
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);