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.