2016-05-06 13 views
30

Sto provando a creare un array che se un valore non esiste, viene aggiunto ma, tuttavia, se il valore è presente, vorrei rimuovere anche quel valore dall'array.Usare lodash push su un array solo se il valore non esiste?

Sembra che Lodash dovrebbe essere in grado di fare qualcosa del genere.

Sono interessato ai suggerimenti delle migliori pratiche.

Inoltre vale la pena di sottolineare che sto usando Angular.js

* Aggiornamento *

if (!_.includes(scope.index, val)) { 
    scope.index.push(val); 
} else { 
    _.remove(scope.index, val); 
} 
+0

input di esempio e di uscita sarebbe di aiuto. Inoltre quello che hai provato. –

+0

Nei moderni ambienti JavaScript, sarebbe molto meglio usare un Set piuttosto che un array. – Pointy

risposta

40

Il Set funzione introdotta da ES6 farebbe esattamente questo.

var s = new Set(); 

// Adding alues 
s.add('hello'); 
s.add('world'); 
s.add('hello'); // already exists 

// Removing values 
s.delete('world'); 

var array = Array.from(s); 

Oppure, se si desidera continuare a utilizzare le matrici regolari

function add(array, value) { 
    if (array.indexOf(value) === -1) { 
    array.push(value); 
    } 
} 

function remove(array, value) { 
    var index = array.indexOf(value); 
    if (index !== -1) { 
    array.splice(index, 1); 
    } 
} 

Utilizzando JS vaniglia sopra Lodash è una buona pratica. Rimuove una dipendenza, ti costringe a capire il tuo codice e spesso è più performante.

+0

Qual è il supporto per l'utilizzo del set? –

+0

È in giro da un po '. IE11 però. https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Set – floribon

+1

Sembra che questo simile al codice all'interno della funzione add() sia errato: ** array.indexOf (value)! == -1 **, dovrebbe essere ** array.indexOf (valore) === -1 **. La logica del codice corrente è: se l'elemento esiste già - aggiungi. – Pjotr

1

Usa includes funzione per controllare che reca esiste in array, e remove eliminare esistenti articolo.

function addOrRemove(arr, val) { 
 
    if (!_.includes(arr, val)) { 
 
    arr.push(val); 
 
    } else { 
 
    _.remove(arr, item => item === val); 
 
    } 
 
    console.log(arr); 
 
} 
 

 
var arr = [1, 2, 3]; 
 
addOrRemove(arr, 1); // arr = [2, 3] 
 
addOrRemove(arr, 4); // arr = [2, 3, 4] 
 
addOrRemove(arr, 2); // arr = [3, 4]
<script src="https://raw.githubusercontent.com/lodash/lodash/4.11.2/dist/lodash.min.js"></script>

+0

Mi piace questa risposta alex ma l'ho provato e non sembra funzionare per me. –

+0

Sembra aggiungere molto bene ma non rimuove il valore se la funzione viene nuovamente attivata. Ho aggiornato la mia domanda con uno snippet di codice –

4

Forse _.pull() può aiutare:

var _ = require('lodash'); 

function knock(arr,val){ 
    if(arr.length === _.pull(arr,val).length){ 
     arr.push(val); 
    } 
    return arr; 
} 

muta l'array esistente, elimina i duplicati così:

> var arr = [1,2,3,4,4,5]; 

> knock(arr,4); 
[ 1, 2, 3, 5 ] 

> knock(arr,6); 
[ 1, 2, 3, 5, 6 ] 

> knock(arr,6); 
[ 1, 2, 3, 5 ] 
0

Questo singolo rivestimento dovrebbe fare il lavoro. Se l'elemento da inserire non esiste, inserisce l'elemento e restituisce la lunghezza della matrice risultante. Se l'elemento esiste nella matrice, cancella l'elemento e restituisce l'elemento eliminato in una matrice separata.

var arr = [1,2,3,4,5], 
 
    aod = (a,e,i=0) => !!~(i = a.indexOf(e)) ? a.splice(i,1) : a.push(e); 
 
    
 
document.write("<pre>" + JSON.stringify(aod(arr,6)) + JSON.stringify(arr) + "</pre>"); 
 
document.write("<pre>" + JSON.stringify(aod(arr,6)) + JSON.stringify(arr) + "</pre>");

pozzo realmente Odio spinta poiché restituisce il valore della lunghezza matrice risultante che è il più delle volte inutile. Preferirei avere un riferimento alla matrice risultante da restituire in modo da poter concatenare le funzioni. Di conseguenza, un modo semplice per raggiungerlo è;

var arr = [1,2,3,4,5], 
 
    aod = (a,e,i=0) => !!~(i = a.indexOf(e)) ? a.splice(i,1) : (a.push(e),a); 
 
     
 
document.write("<pre>" + JSON.stringify(aod(arr,6)) + JSON.stringify(arr) + "</pre>"); 
 
document.write("<pre>" + JSON.stringify(aod(arr,6)) + JSON.stringify(arr) + "</pre>");

Così ora questo è ragionevolmente chainable.

22

È possibile utilizzare _.union

_.union(scope.index, [val]);