it-swarm.com.de

javascript Filter Array mehrere Bedingungen

Ich möchte ein Array von Objekten vereinfachen. Nehmen wir an, ich habe folgendes 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'
}];

Und Objekt filtern:

var filter = {address: 'England', name: 'Mark'};

Zum Beispiel muss ich alle Benutzer nach Adresse und Namen filtern. Daher durchläuft ich die Objekteigenschaften des Filters und checke es aus:

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

Während der ersten Iteration, wenn prop - address gleich 'England' ist, werden zwei Benutzer zum Array-Ergebnis hinzugefügt (mit den Namen Tom und Mark), aber bei der zweiten Iteration, wenn prop name gleich ist Mark, sollte nur der letzte Benutzer zum Array-Ergebnis hinzugefügt werden am Ende mit zwei Elementen in Array. 

Ich habe eine kleine Vorstellung davon, warum es passiert, aber immer noch festgeklebt ist und keine gute Lösung gefunden hat, um das Problem zu beheben. Jede Hilfe ist spürbar. Vielen Dank.

28
user3673623

Das kannst du so machen

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)

45
Raghavendra

Ein weiterer Take für diejenigen von Ihnen, die prägnanten Code genießen.

NOTE: Die FILTER -Methode kann ein zusätzliches this -Argument enthalten. Mit einer E6-Pfeilfunktion können wir das korrekte this erneut verwenden, um ein schönes zu erhalten. Liner.

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>

11
SoEzPz

Sie können dies in einer Zeile tun

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

Kann auch so gemacht werden:

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

Hier ist die ES6-Version der Verwendung der Pfeilfunktion im Filter. Posting dies als Antwort, da die meisten von uns heutzutage ES6 verwenden und den Lesern dabei helfen können, mithilfe der Pfeilfunktion, let und const eine erweiterte Filterung durchzuführen. 

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)

4
Hemadri Dasari

Ich denke das könnte helfen. 

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

1
Coşkun Deniz

Mit Array.Filter () mit Pfeilfunktionen erreichen wir dies mit

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

Hier ist der komplette Ausschnitt

// 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

Wenn Sie mit dem Code den gefilterten Benutzer erhalten möchten, würde ich die for invertieren, um die user auszuwerten.

Hier ein (ungetestetes) Beispiel:

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

funktionale Lösung

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

das sollte die Arbeit erledigen

applyFilters(users, filter);

0
Houssem Zitoun

mit der Zusammensetzung einiger kleiner Helfer:

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