2014-11-03 10 views
10

Sto cercando di utilizzare una mappa di array per filtrare un oggetto un po 'più avanti per prepararlo a inviare al server per il salvataggio. Posso filtrare su 1 valore chiave, che è ottimo, ma voglio fare un ulteriore passo avanti e controllarli contro un booleano interno.Utilizzo della mappa di array per filtrare i risultati con if condizionale

Quindi, in questo momento questo è quello che ho -

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

Questa grande opera per tirare fuori i id, però io non voglio spingerli in questa nuova serie, se il loro valore selezionato == falso, quindi metto un condizionale per filtrare ulteriormente. Funziona un po ', ottengo una matrice di id, ma gli id ​​che hanno .selected == false sono ancora nella matrice, solo con il valore di null. Quindi, se ho 4 articoli in oggetto e 2 di loro sono falsi sembra che questo -

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

La mia domanda è - c'è un modo per farlo senza che i valori nulli messi in là. Grazie per aver letto!

+1

In JS c'è 'metodo Array.prototype.filter' per questo scopo. – pawel

risposta

29

Siete alla ricerca per la funzione .filter():

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

Che sarà producono un array che contiene solo gli oggetti la cui proprietà "selezionato" è true (o truthy).

modificare dispiace mi è stato sempre un caffè e ho perso i commenti - sì, come notato JANDY in un commento, per filtrare e quindi strappare solo i valori "id", sarebbe:

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

Alcune librerie funzionali (come Functional, che a mio avviso non ricevono abbastanza amore) hanno una funzione .pluck() per estrarre i valori di proprietà da un elenco di oggetti, ma JavaScript nativo ha un insieme piuttosto snello di tali strumenti.

+0

Posso quindi trasformare appid in un array di soli id ​​e non l'intero oggetto? Grazie per l'aiuto! – ajmajmajma

+2

@ user3201696 Avrai bisogno di concatenare un '.map()' dopo il filtro, sicuramente possibile. – jAndy

+0

@jAndy fantastico, grazie !! C'è un posto dove posso vedere un esempio, dato che sono sicuro di come concatenare i 2 insieme. Dovrei semplicemente fare la mappa all'interno di questo filtro dopo il ritorno? – ajmajmajma

2

È necessario utilizzare Array.prototype.reduce per eseguire questa operazione. Ho fatto un little JS perf test per verificare che questo è più performante rispetto a fare un .filter + .map.

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

Solo per motivi di chiarezza, ecco il campione .reduce ho usato nel test JSPerf:

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

nota, come di 2/2018 Ridurre + Spingere è più veloce in Chrome ed Edge, ma più lento di Filter + Mappa in Firefox

Problemi correlati