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?

imperium2335
źródło

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.

jAndy
źródło
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);
    }
}
Niet the Dark Absol
źródło
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)
Peracek
źródło
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);
Sridhar
źródło
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.

piątek
źródło
7

W ES6 tylko jedna linia.

const arr = arr.filter(item => item.key !== "some value");

:)

Supun Kavinda
źródło
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

Umair Saleem
źródło
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.

Sandeep piaszczysta
źródło
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>

Parth Raval
źródło
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);
JackTheKnife
źródło
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;
}
Rob M.
źródło
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' });
Gimnath
źródło