web-dev-qa-db-ja.com

javascriptフィルター配列の複数の条件

オブジェクトの配列を単純化したい。次の配列があると仮定しましょう:

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' 2人のユーザーが(TomとMarkの名前で)配列結果に追加されますが、2番目の反復ではprop nameが等しくなるMark最後のユーザーのみを配列結果に追加する必要がありますが、配列の2つの要素になります。

私はなぜそれが起こっているのか少しアイデアを持っていますが、それでもそれに固執し、それを修正するための良い解決策を見つけることができませんでした。すべてのヘルプはかなりのものです。ありがとう。

41
user3673623

このようにすることができます

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)
63
Raghavendra

簡潔なコードを楽しむ人のための別のテイク。

NOTEFILTERメソッドは、追加の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>
16
SoEzPz

これは一列にできます

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

次の方法でも実行できます。

    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);
            })
6
Diogo Rodrigues

これは、フィルターで矢印関数を使用する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)
6
Hemadri Dasari

これが役立つと思います。

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);
  
2
Coşkun Deniz

Array.Filter() with Arrow Functions を使用すると、これを実現できます

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

完全なスニペットはこちら

// 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);
1
Hamza Khanzada

コードの最終性がフィルターされたユーザーを取得することである場合、各反復中に結果配列を減らす代わりに、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;
}
0
The_Black_Smurf

機能的ソリューション

function applyFilters(data, filters) {
  return data.filter(item =>
    Object.keys(filters)
      .map(keyToFilterOn =>
        item[keyToFilterOn].includes(filters[keyToFilterOn]),
      )
      .reduce((x, y) => x && y, true),
  );
}

これは仕事をするはずです

applyFilters(users, filter);

0
Houssem Zitoun

いくつかの小さなヘルパーの構成:

const filter = {address: 'England', name: 'Mark'};
console.log( 
  users.filter(and(map(propMatches)(filter)))
)

function propMatches<T>(property: string, value: any) {
  return (item: T): boolean => item[property] === value
}

function map<T>(mapper: (key: string, value: any, obj: T) => (item:T) => any) {
  return (obj: T) => {
    return Object.keys(obj).map((key) => {
      return mapper(key, obj[key], obj)
    });
  }
}

export function and<T>(predicates: ((item: T) => boolean)[]) {
  return (item: T) =>
    predicates.reduce(
        (acc: boolean, predicate: (item: T) => boolean) => {
            if (acc === undefined) {
                return !!predicate(item);
            }
            return !!predicate(item) && acc;
        },
        undefined // initial accumulator value
    );
}
0
nils petersohn