javascript过滤器数组的多个条件

use*_*623 50 javascript arrays filter

我想简化一个对象数组.我们假设我有以下数组:

var users = [{
    name: 'John',
    email: 'johnson@mail.com',
    age: 25,
    address: 'USA'
    },
    {
        name: 'Tom',
        email: 'tom@mail.com',
        age: 35,
        address: 'England'
    },
    {
        name: 'Mark',
        email: 'mark@mail.com',
        age: 28,
        address: 'England'
}];
Run Code Online (Sandbox Code Playgroud)

并过滤对象:

var filter = {address: 'England', name: 'Mark'};
Run Code Online (Sandbox Code Playgroud)

例如,我需要按地址和名称过滤所有用户,所以我循环过滤器对象属性并检查出来:

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;
}
Run Code Online (Sandbox Code Playgroud)

因此,第一次迭代期间,当prop - address将等于'England'两个用户将被添加到阵列结果(与名汤和Mark),但在第二次迭代时,prop name就等于Mark只在最后一个用户应添加到阵列的结果,但我出现了两个数组中的元素.

我有一个小小的想法,为什么它发生但仍然坚持它,无法找到一个很好的解决方案来解决它.任何帮助都很明显.谢谢.

Rag*_*dra 70

你可以这样做

var filter = {
  address: 'England',
  name: 'Mark'
};
var users = [{
    name: 'John',
    email: 'johnson@mail.com',
    age: 25,
    address: 'USA'
  },
  {
    name: 'Tom',
    email: 'tom@mail.com',
    age: 35,
    address: 'England'
  },
  {
    name: 'Mark',
    email: 'mark@mail.com',
    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)
Run Code Online (Sandbox Code Playgroud)

  • 很乐意帮助:)我也从stackoverflow中学到了很多东西 (4认同)
  • 您应该为过滤器变量选择其他名称.为变量提供受保护的名称是一种糟糕的编码习惯.特别是因为你最后使用该受保护的名称几行后调用Array.prototype.filter方法. (3认同)

SoE*_*zPz 18

对于那些喜欢简洁代码的人来说,另一种看法.

注意:FILTER方法可以使用额外的这个参数,然后使用E6箭头函数,我们可以重复使用正确的这个来获得一个漂亮的单行.

var users = [{name: 'John',email: 'johnson@mail.com',age: 25,address: 'USA'},
             {name: 'Tom',email: 'tom@mail.com',age: 35,address: 'England'},
             {name: 'Mark',email: 'mark@mail.com',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);
Run Code Online (Sandbox Code Playgroud)
<div id="result"></div>
Run Code Online (Sandbox Code Playgroud)


小智 18

users.filter(o => o.address == 'England' && o.name == 'Mark')
Run Code Online (Sandbox Code Playgroud)

对于 es6 来说好多了。或者你可以使用 || (或)这样的运算符

users.filter(o => {return (o.address == 'England' || o.name == 'Mark')})
Run Code Online (Sandbox Code Playgroud)


cyb*_*age 13

你可以排成一行

users = users.filter(obj => obj.name == filter.name && obj.address == filter.address)
Run Code Online (Sandbox Code Playgroud)

  • 这假设您有名称和地址作为过滤器 (6认同)
  • @EddieFreeman 如果您不知道您将拥有哪些过滤器,您将如何解决这个问题? (2认同)

pms*_*ani 10

改进这里的好答案,以下是我的解决方案:

const rawData = [
  { name: 'John', email: 'johnson@mail.com', age: 25, address: 'USA' },
  { name: 'Tom', email: 'tom@mail.com', age: 35, address: 'England' },
  { name: 'Mark', email: 'mark@mail.com', age: 28, address: 'England' }
]
const filters = { address: 'England', age: 28 }

const filteredData = rawData.filter(i =>
  Object.entries(filters).every(([k, v]) => i[k] === v)
)
Run Code Online (Sandbox Code Playgroud)


Ham*_*ada 9

使用Array.Filter()箭头函数,我们可以使用

users = users.filter(x => x.name == 'Mark' && x.address == 'England');

这是完整的片段

// initializing list of users
var users = [{
    name: 'John',
    email: 'johnson@mail.com',
    age: 25,
    address: 'USA'
  },
  {
    name: 'Tom',
    email: 'tom@mail.com',
    age: 35,
    address: 'England'
  },
  {
    name: 'Mark',
    email: 'mark@mail.com',
    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);
Run Code Online (Sandbox Code Playgroud)


NIK*_*C M 8

具有 AND 条件的动态过滤器

过滤掉性别 = 'm' 的人

var people = [
    {
        name: 'john',
        age: 10,
        gender: 'm'
    },
    {
        name: 'joseph',
        age: 12,
        gender: 'm'
    },
    {
        name: 'annie',
        age: 8,
        gender: 'f'
    }
]
var filters = {
    gender: 'm'
}

var out = people.filter(person => {
    return Object.keys(filters).every(filter => {
        return filters[filter] === person[filter]
    });
})


console.log(out)
Run Code Online (Sandbox Code Playgroud)

过滤掉性别 = 'm' 且姓名 = 'joseph' 的人

var people = [
    {
        name: 'john',
        age: 10,
        gender: 'm'
    },
    {
        name: 'joseph',
        age: 12,
        gender: 'm'
    },
    {
        name: 'annie',
        age: 8,
        gender: 'f'
    }
]
var filters = {
    gender: 'm',
    name: 'joseph'
}

var out = people.filter(person => {
    return Object.keys(filters).every(filter => {
        return filters[filter] === person[filter]
    });
})


console.log(out)
Run Code Online (Sandbox Code Playgroud)

您可以根据需要提供任意多个过滤器。


Coş*_*niz 6

我认为这可能会有所帮助。

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.every(val => item.category.indexOf(val) > -1)
);

console.log(filteredResults);
  
Run Code Online (Sandbox Code Playgroud)


Dio*_*ues 6

也可以这样做:

    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);
            })
Run Code Online (Sandbox Code Playgroud)


Hem*_*ari 6

这是在过滤器中使用箭头功能的ES6版本。之所以将其发布为答案是因为我们大多数人现在都在使用ES6,这可能会帮助读者使用箭头功能let和const以高级方式进行过滤。

const filter = {
  address: 'England',
  name: 'Mark'
};
let users = [{
    name: 'John',
    email: 'johnson@mail.com',
    age: 25,
    address: 'USA'
  },
  {
    name: 'Tom',
    email: 'tom@mail.com',
    age: 35,
    address: 'England'
  },
  {
    name: 'Mark',
    email: 'mark@mail.com',
    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)
Run Code Online (Sandbox Code Playgroud)