Javascript javascript过滤数组多个条件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31831651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javascript filter array multiple conditions
提问by user3673623
I want to simplify an array of objects. Let's assume that I have following array:
我想简化一组对象。让我们假设我有以下数组:
var users = [{
name: 'John',
email: '[email protected]',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: '[email protected]',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: '[email protected]',
age: 28,
address: 'England'
}];
And filter object:
和过滤对象:
var filter = {address: 'England', name: 'Mark'};
For example i need to filter all users by address and name, so i do loop through filter object properties and check it out:
例如,我需要按地址和名称过滤所有用户,所以我循环过滤器对象属性并检查它:
function filterUsers (users, filter) {
var result = [];
for (var prop in filter) {
if (filter.hasOwnProperty(prop)) {
//at the first iteration prop will be address
for (var i = 0; i < filter.length; i++) {
if (users[i][prop] === filter[prop]) {
result.push(users[i]);
}
}
}
}
return result;
}
So during first iteration when prop - address
will be equal 'England'
two users will be added to array result (with name Tom and Mark), but on the second iteration when prop name
will be equal Mark
only the last user should be added to array result, but i end up with two elements in array.
因此,在第一次迭代中,何时prop - address
将等于'England'
两个用户将被添加到数组结果中(名称为 Tom 和 Mark),但在第二次迭代中,何时prop name
将Mark
仅将最后一个用户添加到数组结果中,但我最终得到了两个数组中的元素。
I have got a little idea as why is it happening but still stuck on it and could not find a good solution to fix it. Any help is appreciable. Thanks.
我对它为什么会发生有了一点想法,但仍然坚持下去并且找不到解决它的好方法。任何帮助都是可观的。谢谢。
回答by Raghavendra
You can do like this
你可以这样做
var filter = {
address: 'England',
name: 'Mark'
};
var users = [{
name: 'John',
email: '[email protected]',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: '[email protected]',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: '[email protected]',
age: 28,
address: 'England'
}
];
users= users.filter(function(item) {
for (var key in filter) {
if (item[key] === undefined || item[key] != filter[key])
return false;
}
return true;
});
console.log(users)
回答by SoEzPz
Another take for those of you that enjoy succinct code.
对于那些喜欢简洁代码的人来说,这是另一种选择。
NOTE: The FILTERmethod can take an additional thisargument, then using an E6 arrow function we can reuse the correct thisto get a nice one-liner.
注意:FILTER方法可以使用额外的this参数,然后使用 E6 箭头函数我们可以重用正确的this来获得一个不错的单行。
var users = [{name: 'John',email: '[email protected]',age: 25,address: 'USA'},
{name: 'Tom',email: '[email protected]',age: 35,address: 'England'},
{name: 'Mark',email: '[email protected]',age: 28,address: 'England'}];
var query = {address: "England", name: "Mark"};
var result = users.filter(search, query);
function search(user){
return Object.keys(this).every((key) => user[key] === this[key]);
}
// |----------------------- Code for displaying results -----------------|
var element = document.getElementById('result');
function createMarkUp(data){
Object.keys(query).forEach(function(key){
var p = document.createElement('p');
p.appendChild(document.createTextNode(
key.toUpperCase() + ': ' + result[0][key]));
element.appendChild(p);
});
}
createMarkUp(result);
<div id="result"></div>
回答by Abhishek Chandran
You can do this in a line
您可以在一行中执行此操作
users = users.filter(obj => obj.name == filter.name && obj.address == filter.address)
回答by Diogo Rodrigues
Can also be done this way:
也可以这样做:
this.users = this.users.filter((item) => {
return (item.name.toString().toLowerCase().indexOf(val.toLowerCase()) > -1 ||
item.address.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
item.age.toLowerCase().indexOf(val.toLowerCase()) > -1 ||
item.email.toLowerCase().indexOf(val.toLowerCase()) > -1);
})
回答by Hemadri Dasari
Here is ES6 version of using arrow function in filter. Posting this as an answer because most of us are using ES6 these days and may help readers to do filter in advanced way using arrow function, let and const.
这是在过滤器中使用箭头函数的 ES6 版本。将此作为答案发布,因为我们大多数人现在都在使用 ES6,并且可以帮助读者使用箭头函数、let 和 const 以高级方式进行过滤。
const filter = {
address: 'England',
name: 'Mark'
};
let users = [{
name: 'John',
email: '[email protected]',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: '[email protected]',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: '[email protected]',
age: 28,
address: 'England'
}
];
users= users.filter(item => {
for (let key in filter) {
if (item[key] === undefined || item[key] != filter[key])
return false;
}
return true;
});
console.log(users)
回答by Hamza Khanzada
Using Array.Filter()with Arrow Functionswe can achieve this using
使用Array.Filter()和箭头函数,我们可以使用
users = users.filter(x => x.name == 'Mark' && x.address == 'England');
users = users.filter(x => x.name == 'Mark' && x.address == 'England');
Here is the complete snippet
这是完整的片段
// initializing list of users
var users = [{
name: 'John',
email: '[email protected]',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: '[email protected]',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: '[email protected]',
age: 28,
address: 'England'
}
];
//filtering the users array and saving
//result back in users variable
users = users.filter(x => x.name == 'Mark' && x.address == 'England');
//logging out the result in console
console.log(users);
回答by Richard Richie
In lodash,
在 lodash 中,
_.filter(users,{address: 'England', name: 'Mark'})
In es6,
在es6中,
users.filter(o => o.address == 'England' && o.name == 'Mark')
回答by Co?kun Deniz
I think this might help.
我认为这可能会有所帮助。
const filters = ['a', 'b'];
const results = [
{
name: 'Result 1',
category: ['a']
},
{
name: 'Result 2',
category: ['a', 'b']
},
{
name: 'Result 3',
category: ['c', 'a', 'b', 'd']
}
];
const filteredResults = results.filter(item =>
filters
.map(val => item.category.indexOf(val))
.map(val => (val > -1 ? true : false))
.reduce((acc, cum) => acc && cum)
);
console.log(filteredResults);
回答by The_Black_Smurf
If the finality of you code is to get the filtered user, I would invert the for
to evaluate the user
instead of reducing the result array during each iteration.
如果您的代码最终要获得过滤后的用户,我会反转for
来评估user
而不是在每次迭代期间减少结果数组。
Here an (untested) example:
这是一个(未经测试的)示例:
function filterUsers (users, filter) {
var result = [];
for (i=0;i<users.length;i++){
for (var prop in filter) {
if (users.hasOwnProperty(prop) && users[i][prop] === filter[prop]) {
result.push(users[i]);
}
}
}
return result;
}
回答by Houssem Zitoun
functional solution
功能解决方案
function applyFilters(data, filters) {
return data.filter(item =>
Object.keys(filters)
.map(keyToFilterOn =>
item[keyToFilterOn].includes(filters[keyToFilterOn]),
)
.reduce((x, y) => x && y, true),
);
}
this should do the job
这应该可以完成工作
applyFilters(users, filter);
applyFilters(users, filter);