2016-05-06 12 views
30

Próbuję utworzyć tablicę, która jeśli wartość nie istnieje, jest dodawana, ale jednak jeśli wartość jest tam, chciałbym również usunąć tę wartość z tablicy.Używając lodash, wypychaj do tablicy tylko wtedy, gdy wartość nie istnieje?

Wygląda na to, że Lodash powinien móc coś takiego zrobić.

Interesują mnie sugestie dotyczące najlepszych praktyk.

Ponadto warto podkreślić, że używam angularjs

* Aktualizacja *

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

wejście i wyjście próbki pomoże. Plus, co próbowaliście. –

+0

W nowoczesnych środowiskach JavaScript byłoby znacznie lepiej używać zestawu niż tablicy. – Pointy

Odpowiedz

40

Set funkcja wprowadzona przez ES6 zrobi dokładnie to.

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

Albo jeśli chcesz nadal używać zwykłych tablic

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

Korzystanie waniliowy JS nad Lodash jest dobrą praktyką. Usuwa zależność, zmusza do zrozumienia kodu i często jest bardziej wydajny.

+0

Co to jest obsługa zestawu? –

+0

Już od jakiegoś czasu. IE11 jednak. https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Set – floribon

+1

Wygląda tak, jakby kod w funkcji add() był nieprawidłowy: ** array.indexOf (value)! == -1 **, zamiast tego powinno być ** tablica.indexOf (wartość) === -1 **. Bieżąca logika kodu: jeśli element już istnieje - dodaj. – Pjotr

1

Zastosowanie includes funkcja celu sprawdzenia, czy istnieje pozycja jest w tablicy, a remove usunąć istniejący pozycja.

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

Bardzo podoba mi się ta odpowiedź, ale spróbowałem i wydaje mi się, że nie działa ona dla mnie. –

+0

Wygląda na to, że dodaje się bardzo dobrze, ale nie usuwa wartości, jeśli funkcja zostanie ponownie uruchomiona. Zaktualizowałem moje pytanie za pomocą fragmentu kodu. –

4

Może _.pull() może pomóc:

var _ = require('lodash'); 

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

mutuje istniejąca macierz, usuwa duplikaty, a także:

> 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

Ten jeden liner powinien wykonać zadanie. Jeśli element do wstawienia nie istnieje, wstawia element i zwraca długość wynikowej tablicy. Jeśli element istnieje w tablicy, usuwa element i zwraca usunięty element w osobnej tablicy.

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

No faktycznie nienawidzę pchnięcie, ponieważ zwraca wartość wynikową długość tablicy, która jest przez większość czasu bezużyteczne. Wolałbym mieć odniesienie do wynikowej tablicy, która ma zostać zwrócona, aby można było łączyć funkcje. Odpowiednio prosty sposób na osiągnięcie tego jest;

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

Więc teraz to jest rozsądnie chainable.

22

Można użyć _.union

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