Usuń element tablicy na podstawie właściwości obiektu


270

Mam szereg takich obiektów:

var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];

Jak usunąć konkretny na podstawie jego właściwości?

np. Jak usunąć obiekt tablicy z „pieniędzmi” jako właściwością pola?

Odpowiedzi:


382

Jedna możliwość:

myArray = myArray.filter(function( obj ) {
    return obj.field !== 'money';
});

Pamiętaj, że filtertworzy nową tablicę. Żadne inne zmienne odnoszące się do oryginalnej tablicy nie otrzymałyby przefiltrowanych danych, chociaż aktualizujesz oryginalną zmienną myArrayo nowe odwołanie. Używaj ostrożnie.


6
Uwaga: filter()jest dostępna tylko dla Internet Explorera 9+
jessegavin

@jessegavin rzeczywiście. Powinienem wspomnieć, że dostępnych jest wiele dobrych bibliotek shim es5 , które naśladują funkcjonalność (na wypadek, gdybyś chciał obsługiwać starsze przeglądarki)
jAndy

3
filter()tworzy nową tablicę, co jest w porządku, jeśli możesz ponownie przypisać zmienną i wiedzieć, że nie ma innych obszarów kodu, które mają do niej odniesienia. To nie zadziała, jeśli będziesz musiał zmodyfikować oryginalny obiekt tablicy.
Brian Glick,

2
Co jeśli tablica jest strukturą drzewa przedDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {„id”: 23, „name”: „zmieniono test 23”}]}] i chcę usunąć identyfikator: 23
zapomniałem

@forgottofly dobry punkt - odpowiedź działa tylko w ograniczonych przypadkach. Czy znalazłeś odpowiedź na swoje pytanie?
JackTheKnife,

88

Iteruj przez tablicę i znajdź splicete, których nie chcesz. Aby ułatwić korzystanie, iteruj wstecz, abyś nie musiał brać pod uwagę rzeczywistej natury tablicy:

for (var i = myArray.length - 1; i >= 0; --i) {
    if (myArray[i].field == "money") {
        myArray.splice(i,1);
    }
}

3
co rozumiesz przez żywy charakter tablicy? @Neit the Dark Absol
sisimh

29
@sisimh ma na myśli, że jeśli wykonasz iterację do przodu w tablicy, używając jej długości jako części logiki iteracji, a jej długość zmienia się, ponieważ ma elementy usunięte lub dodane, możesz skończyć zbieganiem z końca tablicy lub nie wykonując operacji dla każdy element w tablicy. Cofanie się sprawia, że ​​jest to znacznie mniej prawdopodobne, ponieważ działa w kierunku statycznego indeksu 0, a nie ruchomej długości.
Klors,

2
Co jeśli tablica jest strukturą drzewa przedDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {„id”: 23, „name”: „zmieniono test 23”}]}] i chcę usunąć identyfikator: 23
zapomniałem

To dość oczywiste, ale jeśli oczekujesz tylko usunięcia pojedynczego unikalnego elementu, możesz wrzucić przerwę do instrukcji „if” w celu zwiększenia wydajności, aby pętla nie musiała niepotrzebnie powtarzać całej reszty tablicy.
Patrick Borkowicz

@Klors Dzięki za wyjaśnienie. Czy dobrze jest zawsze czytać tablicę wstecz, jak w odpowiedzi?
kittu

37

Powiedz, że chcesz usunąć drugi obiekt za pomocą jego właściwości pola.

Z ES6 jest to takie proste.

myArray.splice(myArray.findIndex(item => item.field === "cStatus"), 1)

6
Próbowałem tego, ale zamiast „usuwać” trzeci element z tablicy OP, kod „filtrował” i wyświetlał tylko trzeci element.
Compaq LE2202x

1
@ CompaqLE2202x 2 lata później prawdopodobnie jest to już dla ciebie oczywiste, ale dla przyszłych programistów: splicezmienia oryginalną tablicę, więc wartość, którą otrzymujesz, to element, który został usunięty, ale jeśli przyjrzysz się myArraytemu elementowi, będzie go brakować.
David Mulder

16

Możesz użyć lodIsa findIndex, aby uzyskać indeks określonego elementu, a następnie go użyć.

myArray.splice(_.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

Aktualizacja

Możesz także użyć ESI findIndex ()

Metoda findIndex () zwraca indeks pierwszego elementu w tablicy, który spełnia podaną funkcję testową. W przeciwnym razie zwracane jest -1.

myArray.splice(myArray.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

Co to jest tablica jest strukturą drzewa?
zapomniałem

@forgottofly struktura drzewa? Myślę, że myArraytutaj jest szereg obiektów.
Sridhar

3
Co jeśli tablica jest strukturą drzewa var przedDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {„id”: 23, „name”: „zmieniono test 23”}]}] i chcę usunąć identyfikator: 23
zapomniałem

9

Oto kolejna opcja przy użyciu jQuery grep. Podaj truejako trzeci parametr, aby zapewnić, że grep usuwa elementy pasujące do twojej funkcji.

users = $.grep(users, function(el, idx) {return el.field == "money"}, true)

Jeśli już używasz jQuery, nie jest wymagana podkładka dystansowa, co może być przydatne w przeciwieństwie do używania Array.filter.



3

Poniżej znajduje się kod, jeśli nie używasz jQuery. Próbny

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];

alert(myArray.length);

for(var i=0 ; i<myArray.length; i++)
{
    if(myArray[i].value=='money')
        myArray.splice(i);
}

alert(myArray.length);

Możesz także użyć biblioteki podkreślania, która ma wiele funkcji.

Underscore to biblioteka paska narzędzi dla JavaScript, która zapewnia wiele funkcji programowania funkcjonalnego


5
To bardzo niebezpieczny przykład pozostawienia w sieci ... działa z przykładowymi danymi, ale nie z niczym innym. splice (i) oznacza, że ​​usunie wszystkie elementy w tablicy, zaczynając od i po pierwszej instancji, w której wartość to pieniądz, co wcale nie spełnia wymogu z op. Jeśli zmienilibyśmy na łączenie (i, 1), byłoby to nadal niepoprawne, ponieważ nie oceniałoby następnego kolejnego elementu (musiałbyś również zmniejszać i). Dlatego powinieneś przetwarzać operacje usuwania w tablicach wstecz, aby usunąć pozycja nie zmienia indeksów kolejnych pozycji do przetworzenia
Chris Schaller

3
var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];
console.log(myArray.length); //3
myArray = $.grep(myArray, function(element, index){return element.field == "money"}, true);
console.log(myArray.length); //2

Element jest obiektem w tablicy. Trzeci parametr trueoznacza zwróci tablicę elementów, która zawiedzie logikę funkcji, falseoznacza, że ​​zwróci tablicę elementów, która zawiedzie logikę funkcji.


3

Za pomocą biblioteki lodash :

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];
var newArray = _.remove(myArray, function(n) {
  return n.value === 'money';;
});
console.log('Array');
console.log(myArray);
console.log('New Array');
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>


2

W oparciu o niektóre komentarze powyżej poniżej znajduje się kod usuwania obiektu na podstawie nazwy klucza i wartości klucza

 var items = [ 
  { "id": 3.1, "name": "test 3.1"}, 
  { "id": 22, "name": "test 3.1" }, 
  { "id": 23, "name": "changed test 23" } 
  ]

    function removeByKey(array, params){
      array.some(function(item, index) {
        return (array[index][params.key] === params.value) ? !!(array.splice(index, 1)) : false;
      });
      return array;
    }

    var removed = removeByKey(items, {
      key: 'id',
      value: 23
    });

    console.log(removed);

1

Rozwiązanie jAndy jest prawdopodobnie najlepsze, ale jeśli nie możesz polegać na filtrze, możesz zrobić coś takiego:

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: "money"}
];

myArray.remove_key = function(key){
    var i = 0, 
        keyval = null;
    for( ; i < this.length; i++){
        if(this[i].field == key){
            keyval = this.splice(i, 1);
            break;
        }
    }
    return keyval;
}

1
Dlaczego nie mogłem polegać na filter ()?
imperium2335

2
Ponieważ jest częścią JavaScript 1.6, który nie jest obsługiwany przez IE8 i starsze przeglądarki.
Rob M.

-1

Korzystanie z biblioteki Lodash jest proste

_.remove(myArray , { field: 'money' });
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.