2015-08-05 4 views
14

Я хочу упростить массив объектов. Давайте предположим, что у меня есть следующий массив:javascript filter array multiple conditions

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 filter = {address: 'England', name: 'Mark'}; 

Например, мне нужно, чтобы отфильтровать всех пользователей по адресу и имени, поэтому я делаю петлю через свойства объекта фильтра и проверить его из:

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; 
} 

Так что во время первой итерации, когда prop - address будет равна 'England' два пользователи будут добавлены в результате массив (с именем Тома и Марка), но на второй итерации, когда prop name будет равен Mark, только последний пользователь должен быть добавлен к результату массива, но в итоге я получаю два элемента в массиве.

У меня есть небольшая идея, почему это происходит, но все еще застряло на ней и не может найти хорошее решение для ее устранения. Любая помощь заметна. Благодарю.

+0

почему вам цикл через пользователей в 2 раза? – webduvet

ответ

32

вы можете сделать, как этот

var filter = {address: 'England', name: 'Mark'}; 
users = users.filter(function(item) { 
    for(var key in filter) { 
     if(item[key] === undefined || item[key] != filter[key]) 
      return false; 
    } 
    return true; 
}); 
+0

спасибо за ответ, он помог – user3673623

+2

Счастлив помочь :) Мне тоже многому учусь от stackoverflow – Raghavendra

+0

это хорошо, но на самом деле я получаю Uncaught ReferenceError: фильтр не определен –

0

Если окончательность вас код, чтобы получить отфильтрованный пользователя, я бы инвертировать for оценить user вместо уменьшения массива результата во время каждой итерации.

Здесь с (непроверенных), например:

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; 
} 
1

Я думаю, что это может помочь.

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); 
 

4

Another take for those of you that enjoy succinct code.

ПРИМЕЧАНИЕ: ФИЛЬТР метод может принимать дополнительный этот аргумент, то с помощью функции со стрелкой E6 мы можем использовать правильный этот, чтобы получить хороший однострочный.

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>

0

Вы можете сделать это в строке

users = users.filter(obj => obj.name == filter.name && obj.address == filter.address)