Usuń obiekt z tablicy za pomocą JavaScript

547

Jak mogę usunąć obiekt z tablicy? Życzę, aby usunąć obiekt, który zawiera nazwę Kristianod someArray. Na przykład:

someArray = [{name:"Kristian", lines:"2,5,10"},
             {name:"John", lines:"1,19,26,96"}];

Chcę osiągnąć:

someArray = [{name:"John", lines:"1,19,26,96"}];
Clem
źródło
3
Do Twojej wiadomości cofnąłem edycję tego pytania, więc składnia tablicy jest znowu niepoprawna i wszystkie te odpowiedzi są w kontekście.
Dunhamzzz,
2
Następnie składnia tablicy została ponownie „poprawiona” (dwukrotnie), aby odpowiedzi nie były już kontekstowe.
Teepeemm,
4
W jaki sposób błąd składniowy pomaga nadać sensowi niektóre odpowiedzi?
Samy Bencherif
1
@SamyBencherif - Niektóre odpowiedzi jednoznacznie odnoszą się do błędu składniowego w oryginalnej wersji pytania, więc jeśli usuniesz ten błąd składniowy, te odpowiedzi mówią teraz o czymś, co nie istnieje.
nnnnnn

Odpowiedzi:

778

Możesz użyć kilku metod, aby usunąć elementy z tablicy:

//1
someArray.shift(); // first element removed
//2
someArray = someArray.slice(1); // first element removed
//3
someArray.splice(0, 1); // first element removed
//4
someArray.pop(); // last element removed
//5
someArray = someArray.slice(0, a.length - 1); // last element removed
//6
someArray.length = someArray.length - 1; // last element removed

Jeśli chcesz usunąć element na miejscu x, użyj:

someArray.splice(x, 1);

Lub

someArray = someArray.slice(0, x).concat(someArray.slice(-x));

Odpowiedz na komentarz @ chill182 : możesz usunąć jeden lub więcej elementów z tablicy za pomocą Array.filterlub w Array.splicepołączeniu z Array.findIndex(patrz MDN ), np.

// non destructive filter > noJohn = John removed, but someArray will not change
let someArray = getArray();
let noJohn = someArray.filter( el => el.name !== "John" ); 
log("non destructive filter > noJohn = ", format(noJohn));
log(`**someArray.length ${someArray.length}`);

// destructive filter/reassign John removed > someArray2 =
let someArray2 = getArray();
someArray2 = someArray2.filter( el => el.name !== "John" );
log("", "destructive filter/reassign John removed > someArray2 =", 
  format(someArray2));
log(`**someArray2.length ${someArray2.length}`);

// destructive splice /w findIndex Brian remains > someArray3 =
let someArray3 = getArray();
someArray3.splice(someArray3.findIndex(v => v.name === "Kristian"), 1);
someArray3.splice(someArray3.findIndex(v => v.name === "John"), 1);
log("", "destructive splice /w findIndex Brian remains > someArray3 =", 
  format(someArray3));
log(`**someArray3.length ${someArray3.length}`);

// Note: if you're not sure about the contents of your array, 
// you should check the results of findIndex first
let someArray4 = getArray();
const indx = someArray4.findIndex(v => v.name === "Michael");
someArray4.splice(indx, indx >= 0 ? 1 : 0);
log("", "check findIndex result first > someArray4 (nothing is removed) > ",
  format(someArray4));
log(`**someArray4.length (should still be 3) ${someArray4.length}`);

function format(obj) {
  return JSON.stringify(obj, null, " ");
}

function log(...txt) {
  document.querySelector("pre").textContent += `${txt.join("\n")}\n`
}

function getArray() {
  return [ {name: "Kristian", lines: "2,5,10"},
           {name: "John", lines: "1,19,26,96"},
           {name: "Brian", lines: "3,9,62,36"} ];
}
<pre>
**Results**

</pre>

KooiInc
źródło
2
@Klemzy nie miałeś na myśli, że nie przez indeks? według wartości ...?
Royi Namir,
328
Pierwotne pytanie dotyczyło sposobu usunięcia obiektu o nazwie = „Kristian” z tablicy. Twoja odpowiedź zakłada, że ​​jest to pierwszy element w tablicy, ale co, jeśli Kristin nie ma w pierwszym elemencie? Twoja odpowiedź nie działa.
Rochelle C
7
@ chill182: nie jest to konkretna odpowiedź, ale ogólniejsza. Na tej podstawie powinieneś być w stanie wywnioskować metodę usuwania elementów. Jeśli chcesz usunąć element w pozycji x ... może to być wskazówka do usuwania elementów innych niż pierwsze, prawda?
KooiInc
6
Funkcja łączenia była dla mnie pomocna, ale nie powinieneś był ponownie przypisywać someArray. Spowoduje to, że tablica zawiera usunięty element, a nie tablicę wynikową z usuniętym elementem.
Kenn Cal
1
Powinieneś sprawdzić findIndexwynik przed użyciem go splice. Jeśli w tablicy nie ma elementów, które pasują, warunek findIndexzostanie zwrócony, -1a umieszczenie tego bezpośrednio w tablicy splicespowoduje arbitralne usunięcie ostatniego elementu w tablicy.
jdnz
131

Polecam używanie lodash.js lub sugar.js do typowych zadań takich jak to:

// lodash.js
someArray = _.reject(someArray, function(el) { return el.Name === "Kristian"; });

// sugar.js
someArray.remove(function(el) { return el.Name === "Kristian"; });

w większości projektów posiadanie zestawu metod pomocniczych dostarczanych przez takie biblioteki jest dość przydatne.

psyho
źródło
13
Myślę, że przykład podkreślenia jest nieco wyłączony. Powinien byćsomeArray = _.reject(someArray, function(el) { return el.Name === "Kristian"; });
Andy Ford
7
Jeśli nie chcesz używać underscore.js lub sugar.js, możesz to zrobićsomeArray = someArray.filter(function(e) { return e.Name !== "Kristian"; });
BenR
1
Kolejną rzeczą, którą chcę, będą osobne przyciski dla każdego obiektu w tablicy. jeśli chcę usunąć ten konkretny obiekt w klikniętym przycisku tablicy jak to zrobić . Użyłem kątowego js ng-repeat do generowania przedmiotów. czy możesz mi pomóc
Thilak Raj
5
Idę tu pod prąd; sugerowanie, aby jedna obejmowała całą bibliotekę w prostym celu usuwania elementów z obiektów (co js czysto obsługuje po wyjęciu z pudełka, jak pokazuje zaakceptowana odpowiedź), jest złej formie. Dodaje niepotrzebną wagę i złożoność kodu, chyba że jest on już potrzebny do uzyskania bardziej zaawansowanych funkcji biblioteki.
Josh Doebbert
4
Dla prostej operacji nigdy nie
zalecę
130

Czystym rozwiązaniem byłoby użycie Array.filter:

var filtered = someArray.filter(function(el) { return el.Name != "Kristian"; }); 

Problem polega na tym, że nie działa on w przeglądarce IE <9. Można jednak dołączyć kod z biblioteki JavaScript (np. Underscore.js ), która implementuje to w dowolnej przeglądarce.

Jon
źródło
10
Spowoduje to jednak usunięcie wszystkich znalezionych zdarzeń, nie tylko pierwszego
Flavien Volken
4
I zwróci nową tablicę zamiast modyfikować oryginalną. W zależności od przypadku użycia może to być lub nie być to, czego chcesz.
Jochie Nabuurs,
1
@JochieNabuurs to rzeczywiście nowa tablica. Jednak obiekt pozostaje taki sam. Nadal możesz modyfikować wartość każdego obiektu, a będzie on odzwierciedlał obiekt oryginalnej tablicy.
DriLLFreAK100
2
Do tego stopnia, że ​​zwraca nową tablicę, wystarczy zmienić rozwiązanie na someArray = someArray.filter(function(el) { return el.Name != "Kristian"; }); adresy, które nie, nie?
hBrent
93

Co powiesz na to?

$.each(someArray, function(i){
    if(someArray[i].name === 'Kristian') {
        someArray.splice(i,1);
        return false;
    }
});
Allan Taylor
źródło
8
Nie spowoduje to błędu, ponieważ $.each()buforuje długość tablicy przed zapętleniem, więc jeśli usuniesz element, $.each()będzie przebiegał poza końcem (teraz krótszej) tablicy. (Więc wtedy someArray[i]będzie undefinedi undefined.namerozbije się.)
nnnnnn
5
Następnie dodaj „return false” po splocie.
Allan Taylor
18
to nie jest javascript. -1
cebulka
20
Należy pamiętać, że ta odpowiedź wymaga jQuery
Clarkey
68

Twoja „tablica”, jak pokazano, jest niepoprawną składnią JavaScript. Nawiasy klamrowe {}dotyczą obiektów o parach nazwa-wartość, ale nawiasy kwadratowe []dotyczą tablic:

someArray = [{name:"Kristian", lines:"2,5,10"}, {name:"John", lines:"1,19,26,96"}];

W takim przypadku możesz użyć .splice()metody, aby usunąć element. Aby usunąć pierwszy element (indeks 0), powiedz:

someArray.splice(0,1);

// someArray = [{name:"John", lines:"1,19,26,96"}];

Jeśli nie znasz indeksu, ale chcesz przeszukać tablicę, aby znaleźć element o nazwie „Kristian” do usunięcia, możesz to zrobić:

for (var i =0; i < someArray.length; i++)
   if (someArray[i].name === "Kristian") {
      someArray.splice(i,1);
      break;
   }

EDYCJA: Właśnie zauważyłem, że twoje pytanie jest oznaczone jako „jQuery”, więc możesz wypróbować $.grep()metodę :

someArray = $.grep(someArray,
                   function(o,i) { return o.name === "Kristian"; },
                   true);
nnnnnn
źródło
Dlaczego dodali przeciążenie? Z pewnością mogłeś po prostu wstawić! = "Kristian". Do czego służy przeciążenie?
markthewizard1234
@ markthewizard1234 - Czy masz na myśli argument „invert” w logice $.grep()? Nie dodaje się wiele w tym przykładzie, w którym tak, mógłbym umieścić !=, ale w innych przypadkach możesz już mieć zdefiniowaną funkcję, która wykonuje test odwrotny do tego, co chcesz grepować, więc zamiast definiować dodatkową funkcję można po prostu użyć tego przeciążenia, aby odwrócić wyniki.
nnnnnn
Ach, więc jeśli masz funkcję otoki zawierającą grep, możesz ustawić wartość logiczną jako parametr. Mam to, dzieki!
markthewizard1234
@ markthewizard1234 - Możesz, ale nie o to mi chodziło: wyobraź sobie, że tak function isEven(num) { return num%2===0 }. Możesz użyć, $.grep(someArray, isEven)aby uzyskać tylko liczby parzyste z tablicy, lub $.grep(someArray, isEven, true)zrobić coś przeciwnego i uzyskać wartości nieparzyste.
nnnnnn
63

ES2015

let someArray = [
               {name:"Kristian", lines:"2,5,10"},
               {name:"John", lines:"1,19,26,96"},
               {name:"Kristian", lines:"2,58,160"},
               {name:"Felix", lines:"1,19,26,96"}
            ];

someArray = someArray.filter(person => person.name != 'John');

To usunie Johna !

Saeid
źródło
4
Człowieku ... Pochodzę z Java, jestem bardzo zdezorientowany, że tak podstawowa rzecz wymaga filtrowania listy ... wtf. To jest najdokładniejsza odpowiedź na pytanie PO, które przeczytałem do tej pory.
codepleb
Tak, to dobre podejście. Chociaż będzie działał również przed ES2015 (ES6). Funkcja filtrowania jest dostępna od wersji 5.1 (2011) ecma-international.org/ecma-262/5.1/#sec-15.4.4.20
user3777549
40

Możesz użyć array.filter ().

na przykład

        someArray = [{name:"Kristian", lines:"2,5,10"},
                     {name:"John", lines:"1,19,26,96"}];

        someArray = someArray.filter(function(returnableObjects){
               return returnableObjects.name !== 'Kristian';
        });

        //someArray will now be = [{name:"John", lines:"1,19,26,96"}];

Funkcje strzałek:

someArray = someArray.filter(x => x.name !== 'Kristian')
daCoda
źródło
Kolejną rzeczą, którą chcę, będą osobne przyciski dla każdego obiektu w tablicy. jeśli chcę usunąć ten konkretny obiekt w klikniętym przycisku tablicy jak to zrobić . Użyłem kątowego js ng-repeat do generowania przedmiotów. czy możesz mi pomóc
Thilak Raj
daCoda co jeśli masz dwa warunki?
Malcolm Salvador,
@MalcolmSalvador powiedz na przykład, jeśli masz inne warunki, możesz napisać to jak poniżej i kontynuować z różnymi && lub || operator w zależności od potrzeb. someArray = someArray.filter (function (returnableObjects) {return returnableObjects.name! == 'Kristian' && cond2Query.age> = 22;});
Biswajit Panday
18

Zrobiłem funkcję dynamiczną, która pobiera obiekty Array, Key i value i zwraca tę samą tablicę po usunięciu pożądanego obiektu:

function removeFunction (myObjects,prop,valu)
        {
             return myObjects.filter(function (val) {
              return val[prop] !== valu;
          });

        }

Pełny przykład: DEMO

var obj = {
            "results": [
              {
                  "id": "460",
                  "name": "Widget 1",
                  "loc": "Shed"
              }, {
                  "id": "461",
                  "name": "Widget 2",
                  "loc": "Kitchen"
              }, {
                  "id": "462",
                  "name": "Widget 3",
                  "loc": "bath"
              }
            ]
            };


        function removeFunction (myObjects,prop,valu)
        {
             return myObjects.filter(function (val) {
              return val[prop] !== valu;
          });

        }


console.log(removeFunction(obj.results,"id","460"));
Bishoy Hanna
źródło
15

Ta funkcja działa dla mnie:

function removeFromArray(array, value) {
    var idx = array.indexOf(value);
    if (idx !== -1) {
        array.splice(idx, 1);
    }
    return array;
}
ggmendez
źródło
Kolejną rzeczą, którą chcę, będą osobne przyciski dla każdego obiektu w tablicy. jeśli chcę usunąć ten konkretny obiekt w klikniętym przycisku tablicy jak to zrobić . Użyłem kątowego js ng-repeat do generowania przedmiotów. czy możesz mi pomóc
Thilak Raj 21.01.16
12

Możesz także spróbować zrobić coś takiego:

var myArray = [{'name': 'test'}, {'name':'test2'}];
var myObject = {'name': 'test'};
myArray.splice(myArray.indexOf(myObject),1);
Mikebarson
źródło
11
someArray = jQuery.grep(someArray , function (value) {
        return value.name != 'Kristian';
});
Andre Morata
źródło
10

Użyj funkcji łączenia na tablicach. Określ pozycję elementu początkowego i długość podsekwencji, którą chcesz usunąć.

someArray.splice(pos, 1);
gabitzish
źródło
8

Głosuj na UndercoreJS dla prostej pracy z tablicami.

Funkcja _.without () pomaga usunąć element:

 _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
    => [2, 3, 4]
Julia Cezar
źródło
Najlepszym rozwiązaniem. Działa z tablicami obiektów.
Azee,
4

Z funkcją strzałki ES 6

let someArray = [
                 {name:"Kristian", lines:"2,5,10"},
                 {name:"John", lines:"1,19,26,96"}
                ];
let arrayToRemove={name:"Kristian", lines:"2,5,10"};
someArray=someArray.filter((e)=>e.name !=arrayToRemove.name && e.lines!= arrayToRemove.lines)
Siddhartha
źródło
3

Najprostszym rozwiązaniem byłoby utworzenie mapy, która przechowuje indeksy dla każdego obiektu według nazwy, w następujący sposób:

//adding to array
var newPerson = {name:"Kristian", lines:"2,5,10"}
someMap[ newPerson.name ] = someArray.length;
someArray.push( newPerson );

//deleting from the array
var index = someMap[ 'Kristian' ];
someArray.splice( index, 1 );
Creynders
źródło
Podoba mi się ten pomysł, ale muszę również zapytać, jakie są limity wykorzystania pamięci dla takiego pomysłu po dodaniu indeksów? Mam tablicę, którą chciałbym zindeksować na 2 różnych polach w obiekcie, więc oprócz oryginalnej tablicy źródłowej mam 2 mapy. Czy to niewielka cena za szybkość wyszukiwania, czy jest rozwiązanie, które byłoby bardziej wydajne z pamięcią?
Brad G.
3

Chociaż prawdopodobnie nie jest to odpowiednie w tej sytuacji, dowiedziałem się innego dnia, że ​​możesz również użyć deletesłowa kluczowego, aby usunąć element z tablicy, jeśli nie musisz zmieniać rozmiaru tablicy, np.

var myArray = [1,2,3];

delete myArray[1];

console.log(myArray[1]); //undefined

console.log(myArray.length); //3 - doesn't actually shrink the array down
dougajmcdonald
źródło
3

Ta odpowiedź

for (var i =0; i < someArray.length; i++)
   if (someArray[i].name === "Kristian") {
      someArray.splice(i,1);
   }

nie działa dla wielu rekordów spełniających warunek. Jeśli masz dwa takie kolejne rekordy, tylko pierwszy jest usuwany, a drugi pomijany. Musisz użyć:

for (var i = someArray.length - 1; i>= 0; i--)
   ...

zamiast .

JarmoP
źródło
2

Wygląda na to, że wystąpił błąd w składni tablicy, więc zakładając, że masz na myśli tablicę, a nie obiekt, Array.splice jest tutaj twoim przyjacielem:

someArray = [{name:"Kristian", lines:"2,5,10"}, {name:"John", lines:"1,19,26,96"}];
someArray.splice(1,1)
Simon Scarfe
źródło
2

Możesz także użyć funkcji mapy .

someArray = [{name:"Kristian", lines:"2,5,10"},{name:"John",lines:"1,19,26,96"}];
newArray=[];
someArray.map(function(obj, index){
    if(obj.name !== "Kristian"){
       newArray.push(obj);
    }
});
someArray = newArray;
console.log(someArray);
solanki ...
źródło
1
Ale jeśli chcesz iterować po tablicy, czy nie lepiej jest użyć dlaEach?
corse32
2

Możesz również użyć some:

someArray = [{name:"Kristian", lines:"2,5,10"},
             {name:"John", lines:"1,19,26,96"}];

someArray.some(item => { 
    if(item.name === "Kristian") // Case sensitive, will only remove first instance
        someArray.splice(someArray.indexOf(item),1) 
})
Artur Grigio
źródło
2

Tego używam.

Array.prototype.delete = function(pos){
    this[pos] = undefined;
    var len = this.length - 1;
    for(var a = pos;a < this.length - 1;a++){
      this[a] = this[a+1];
    }
    this.pop();
  }

To jest tak proste, jak powiedzenie

var myArray = [1,2,3,4,5,6,7,8,9];
myArray.delete(3);

Zastąp dowolną liczbę zamiast trzech. Po oczekiwanym wyniku powinno być:

console.log(myArray); //Expected output 1,2,3,5,6,7,8,9
Matthias S.
źródło
2

Jeśli chcesz usunąć wszystkie wystąpienia danego obiektu (na podstawie pewnych warunków), użyj metody łączenia javascript wewnątrz pętli for.

Ponieważ usunięcie obiektu wpłynęłoby na długość tablicy, należy zmniejszyć licznik o jeden krok, aby kontrola długości pozostała nienaruszona.

var objArr=[{Name:"Alex", Age:62},
  {Name:"Robert", Age:18},
  {Name:"Prince", Age:28},
  {Name:"Cesar", Age:38},
  {Name:"Sam", Age:42},
  {Name:"David", Age:52}
];

for(var i = 0;i < objArr.length; i ++)
{
  if(objArr[i].Age > 20)
  {
    objArr.splice(i, 1);
    i--;  //re-adjust the counter.
  }
}

Powyższy fragment kodu usuwa wszystkie obiekty w wieku powyżej 20 lat.

Obaid
źródło
1

splice (i, 1), gdzie i jest przyrostowym indeksem tablicy, usunie obiekt. Pamiętaj jednak, że połączenie zresetuje również długość tablicy, więc uważaj na „niezdefiniowane”. Korzystając z Twojego przykładu, jeśli usuniesz „Kristian”, to w następnym wykonaniu w pętli będę mieć 2, ale someArray będzie miał długość 1, dlatego jeśli spróbujesz usunąć „John”, otrzymasz błąd „niezdefiniowany” . Jednym z rozwiązań tego, choć nie eleganckim, jest posiadanie osobnego licznika do śledzenia indeksu elementu do usunięcia.

Maksood
źródło
1

Zwraca tylko obiekty z tablicy, których właściwość namenie jest „Kristian”

var noKristianArray = $.grep(someArray, function (el) { return el.name!= "Kristian"; });


Próbny:

 var someArray = [
                {name:"Kristian", lines:"2,5,10"},
                {name:"John", lines:"1,19,26,96"},
                {name:"Kristian", lines:"2,58,160"},
                {name:"Felix", lines:"1,19,26,96"}
                ];
			 
var noKristianArray = $.grep(someArray, function (el) { return el.name!= "Kristian"; });

console.log(noKristianArray);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Legendy
źródło
0

Te koncepcje za pomocą Kendo Grid

var grid = $("#addNewAllergies").data("kendoGrid");

var selectedItem = SelectedCheckBoxList;

for (var i = 0; i < selectedItem.length; i++) {
    if(selectedItem[i].boolKendoValue==true)
    {
        selectedItem.length= 0;
    }
}
Siva Ragu
źródło
-2

Jeśli chcesz uzyskać dostęp do obiektu tablicy i usunąć go, możesz po prostu spróbować czegoś takiego.

// inside some function

let someArray = [ {"ColumnName" : "a", "PropertySerno" : 100005,"UpdateType" : 1},
                  {"ColumnName" : "b", "PropertySerno" : 100202,"UpdateType" : 1,
        "ShowRemoveButton" : true} ];
        
        for (let item of someArray) {
          delete item.ShowRemoveButton;
        }
        console.log(item.outputMappingData.Data);
        
//output will be like that = [ {"ColumnName" : "a", "PropertySerno" : 100005,"UpdateType" : 1},
//                             {"ColumnName" : "b", "PropertySerno" : 100202,"UpdateType" : 1 }];
        

ismailuztemur
źródło