2013-04-14 20 views
18

Zastanawiam się, w jaki sposób chciałbym wdrożyć metodę w javascript, która usuwa wszystkie elementy tablicy, które czynią pewien warunek. (Najlepiej bez użycia jQuery)javascript - usuń element tablicy pod warunkiem

Przykł.

ar = [ 1, 2, 3, 4 ]; 
ar.removeIf(function(item, idx) { 
    return item > 3; 
}); 

Powyższy by przejść każdej pozycji w tablicy i usunąć wszystkie te, które return true dla stanu (na przykład pozycja> 3).

Właśnie zaczynam w javascript i zastanawiałem się, czy ktoś wie o krótkim, skutecznym sposobie wykonania tego.

- aktualizacja -

Byłoby to także wielki, jeśli warunek może pracować na właściwości obiektu, jak również.

Przykł.

ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ]; 
ar.removeIf(function(item, idx) { 
    return item.str == "c"; 
}); 

Jeżeli pozycja zostanie usunięta, jeśli item.str == "c"

- Update2 -

Byłoby miło, gdyby warunki indeks może pracować również.

Przykł.

ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ]; 
ar.removeIf(function(item, idx) { 
    return idx == 2; 
}); 

Odpowiedz

19

Można dodać własną metodę Array że robi coś podobnego, jeśli filter nie działa dla Ciebie.

Array.prototype.removeIf = function(callback) { 
    var i = 0; 
    while (i < this.length) { 
     if (callback(this[i], i)) { 
      this.splice(i, 1); 
     } 
     else { 
      ++i; 
     } 
    } 
}; 

Dla mnie jest to jedna z najfajniejszych funkcji JavaScript. Ian wskazał skuteczniejszy sposób na zrobienie tego samego. Biorąc pod uwagę, że jest to JavaScript, co trochę pomaga:

Array.prototype.removeIf = function(callback) { 
    var i = this.length; 
    while (i--) { 
     if (callback(this[i], i)) { 
      this.splice(i, 1); 
     } 
    } 
}; 

Eliminuje to konieczność nawet martwić się o aktualizację length lub łapanie następny element, jak pracować na swój sposób w lewo zamiast w prawo.

+0

http://jsfiddle.net/n8JEy/3/ To działa. – pickypg

+0

Dzięki, działa świetnie. Podoba mi się, jak to bierze pod uwagę zmiany indeksu poprzez splicing w trakcie iteracji. – dk123

+3

To trochę nieładne. Wypróbuj http://jsfiddle.net/n8JEy/4/ - i nie przekazałeś 'i' do wywołania zwrotnego jako drugiego parametru. – Ian

14

Można użyć Array.filter(), który robi coś przeciwnego:

ar.filter(function(item, idx) { 
    return item <= 3; 
}); 
+2

W górę głowa, która nie jest obsługiwana w IE8 lub poniżej. Powinieneś też zanegować oryginalne wyrażenie, albo powinno to być '<='. – pickypg

+5

Czy Array.filter() nie zwraca nowej tablicy z filtrowanymi elementami? Czy jest coś, co po prostu usuwa elementy z tablicy? – dk123

+0

@ dk123: Nie ma nic wcześniejszego. Będziesz musiał napisać pętlę 'for'., – Blender

19

Można użyć Array filter method.

kod wyglądałby następująco:

ar = [ 1, 2, 3, 4 ]; 
ar = ar.filter(function(item) { 
    return !(item > 3); 
}); 
1

Uwielbiam tego rodzaju pytania i tylko inną wersję ode mnie ...:)

Array.prototype.removeIf = function(expression) { 
    var res = []; 
    for(var idx=0; idx<this.length; idx++) 
    { 
     var currentItem = this[idx]; 
     if(!expression(currentItem)) 
     { 
      res.push(currentItem); 
     } 
    } 
    return res; 
} 

ar = [ 1, 2, 3, 4 ]; 
var result = ar.removeIf(expCallBack); 


console.log(result); 
function expCallBack(item) 
{ 
    return item > 3; 
} 
+0

Czy mogłabyś ewentualnie zmodyfikować (lub dodać inną metodę) swój kod, aby faktycznie usunąć elementy zamiast zwracać nową tablicę? Dziękuję za odpowiedź. – dk123

+2

ktokolwiek zlekceważył to tak źle. jest to najlepsza perfekcyjna odpowiedź spośród wszystkich. sprawdź test przez @Blender jsperf.com/splice-vs-filter. w najnowszych wersjach Firefoksa jest co najmniej 2x szybszy i aż 15-krotnie szybszy – parliament

2

prostu napisać następujący przykład, jeśli warunek może pracować na właściwości obiektu, jak również

var ar = [ {num:1, str:"a"}, {num:2, str:"b"}, {num:3, str:"c"} ]; 
var newArray = []; 
for (var i = 0, len = ar.length; i<len; i++) { 
     if (ar[i].str == "b") 
     {newArray.push(ar[i]);}; 
}; 
console.log(newArray); 

Patrz przykład Live Example

Powiązane problemy