2014-11-03 17 views
10

Ich versuche eine Array-Map zu verwenden, um ein Objekt ein wenig weiter zu filtern, um es zum Senden an den Server zum Speichern vorzubereiten. Ich kann auf 1 Schlüsselwert filtern, was großartig ist, aber ich möchte einen Schritt weiter gehen und sie gegen einen booleschen Wert prüfen.Verwenden von Array-Map zum Filtern von Ergebnissen mit If-Bedingung

So, jetzt ist es das, was ich habe -

$scope.appIds = $scope.applicationsHere.map(function(obj){ 
     if(obj.selected == true){ 
      return obj.id; 
     } 
    }); 

dies die ID der zum Herausziehen funktioniert gut, aber ich mag sie nicht in dieser neuen Reihe, wenn sie ihren gewählter Wert == drücken falsch, also habe ich eine Bedingung gesetzt, um weiter zu filtern. Das funktioniert, ich bekomme ein Array von IDs, aber die IDs, die .selected == false haben, sind immer noch im Array, nur mit dem Wert von null. Also, wenn ich 4 Elemente im Objekt habe und 2 von ihnen sind falsch sieht es so aus -

appIds = {id1, id2, null, null}; 

Meine Frage ist - gibt es eine Möglichkeit, dies zu tun, ohne die Nullen in dort gesetzt werden. Danke fürs Lesen!

+1

In JS gibt es 'Array.prototype.filter' Methode für diesen Zweck. – pawel

Antwort

29

Sie suchen die .filter() Funktion:

$scope.appIds = $scope.applicationsHere.filter(function(obj) { 
    return obj.selected; 
    }); 

Das wird ein Array erzeugen, die nur die Objekte enthält, deren „ausgewählt“ Eigenschaft ist true (oder truthy).

$scope.appIds = $scope.applicationsHere.filter(function(obj) { 
    return obj.selected; 
    }).map(function(obj) { return obj.id; }); 
: -

bearbeiten leider war ich etwas Kaffee bekommen und ich vermisste die Kommentare ja, wie JANDY in einem Kommentar, bemerkte nur die „id“ Werte zu filtern und dann reiß es aus, würde es sein,

Einige funktionale Bibliotheken (wie Functional, die meiner Meinung nach nicht genug Liebe bekommen) haben eine .pluck() Funktion, um Eigenschaftenwerte aus einer Liste von Objekten zu extrahieren, aber natives JavaScript hat eine ziemlich schlanke Reihe solcher Werkzeuge.

+0

Kann ich appids dann in ein Array von nur IDs und nicht das vollständige Objekt verwandeln? danke für Ihre Hilfe! – ajmajmajma

+2

@ user3201696 Sie müssten nach dem Filter eine '.map()' ketten, definitiv möglich. – jAndy

+0

@jAndy super, danke !! Kann ich irgendwo ein Beispiel sehen, da ich sicher bin, wie man die 2 zusammen kettet. Würde ich die Karte innerhalb dieses Filters nach der Rückkehr einfach machen? – ajmajmajma

2

Sie sollten Array.prototype.reduce verwenden, um dies zu tun. Ich habe eine , um zu überprüfen, dass dies leistungsfähiger ist als eine .filter + .map.

$scope.appIds = $scope.applicationsHere.reduce(function(ids, obj){ 
    if(obj.selected === true){ 
     ids.push(obj.id); 
    } 
    return ids; 
}, []); 

Nur aus Gründen der Übersichtlichkeit ist hier die Probe .reduce ich im JSPerf Test verwendet:

var things = [ 
 
    {id: 1, selected: true}, 
 
    {id: 2, selected: true}, 
 
    {id: 3, selected: true}, 
 
    {id: 4, selected: true}, 
 
    {id: 5, selected: false}, 
 
    {id: 6, selected: true}, 
 
    {id: 7, selected: false}, 
 
    {id: 8, selected: true}, 
 
    {id: 9, selected: false}, 
 
    {id: 10, selected: true}, 
 
    ]; 
 
    
 
    \t 
 
var ids = things.reduce((ids, thing) => { 
 
    if (thing.selected) { 
 
    ids.push(thing.id); 
 
    } 
 
    return ids; 
 
}, []); 
 

 
console.log(ids)


EDIT 1

Hinweis, Stand 2/2018 verringern + Drücken schnellste in Chrome ist und Rand, aber langsamer als Filter + Karte in Firefox