Удалить объект из массива с помощью JavaScript


549

Как я могу удалить объект из массива? Я хочу удалить объект, который включает имя Kristianиз someArray. Например:

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

Я хочу добиться:

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


3
К вашему сведению, я откатил редактирование этого вопроса, чтобы синтаксис массива снова был неправильным, и все эти ответы находятся в контексте.
Данхаммзз

2
Затем синтаксис массива снова «исправили» (дважды), чтобы ответы больше не находились в контексте.
Teepeemm

4
Как синтаксическая ошибка помогает сделать некоторые ответы осмысленными?
Сэми Бенчериф

1
@SamyBencherif - Некоторые ответы явно касаются синтаксической ошибки в исходной версии вопроса, поэтому, если вы удалите эту синтаксическую ошибку, эти ответы теперь говорят о том, чего не существует.
nnnnnn

Ответы:


778

Вы можете использовать несколько методов для удаления элементов из массива:

//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

Если вы хотите удалить элемент в позиции x, используйте:

someArray.splice(x, 1);

Или

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

Ответ на комментарий @ chill182 : вы можете удалить один или несколько элементов из массива с помощью Array.filterили в Array.spliceсочетании с Array.findIndex(см. MDN ), например

// 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>


2
@ Клемзи, ты не имел в виду не по индексу? по значению ...?
Ройи Намир

328
В первоначальном вопросе спрашивалось, как удалить объект с именем = "Кристиан" из массива. Ваш ответ предполагает, что это первый элемент в массиве, но что, если Кристин не в первом элементе? Тогда ваш ответ не работает.
Рошель C

7
@ chill182: это не конкретный ответ, а более общий. Из него вы должны быть в состоянии вывести метод удаления элементов. Если вы хотите удалить элемент в позиции x ... может быть подсказка для удаления, кроме первых элементов, верно?
KooiInc

6
Функция склейки была полезна для меня, но вам не нужно было повторно назначать someArray. Это приведет к некоторому массиву, содержащему удаленный элемент, а не к результирующему массиву с удаленным элементом.
Кенн Кэл

1
Вы должны проверить findIndexрезультат, прежде чем использовать его в splice. Если в массиве нет элементов, соответствующих условию, findIndexбудет возвращено условие , -1и его непосредственное включение spliceприведет к произвольному удалению последнего элемента в массиве.
jdnz

131

Я рекомендую использовать lodash.js или sugar.js для общих задач, таких как:

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

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

в большинстве проектов очень полезно иметь набор вспомогательных методов, предоставляемых такими библиотеками.


13
Я думаю, что пример подчеркивания слегка отклонен. Должно бытьsomeArray = _.reject(someArray, function(el) { return el.Name === "Kristian"; });
Энди Форд

7
Если вы не хотите использовать underscore.js или sugar.js, вы можете сделать этоsomeArray = someArray.filter(function(e) { return e.Name !== "Kristian"; });
BenR

1
Еще одна вещь, которую я хочу, будут отдельные кнопки для каждого объекта в массиве. если я хочу удалить этот конкретный объект в кнопке массива нажал. как это сделать . Я использовал угловой JS NG-повтор для создания предметов. Вы можете мне помочь
Тилак Радж

5
Собираюсь идти против зерна здесь; предлагать включать целую библиотеку для простой цели удаления элементов из объектов (что js безошибочно поддерживает из коробки, как показывает принятый ответ) - плохая форма. Это добавляет ненужный вес и сложность вашему коду, если только он вам не нужен для более мощных функций, предоставляемых библиотекой.
Джош Добберт

4
Для простой работы я никогда не буду рекомендовать включать библиотеку
Munna Bhakta

130

Чистое решение будет использовать Array.filter:

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

Проблема в том, что он не работает в IE <9. Однако вы можете включить код из библиотеки Javascript (например, underscore.js ), который реализует это для любого браузера.


10
Это, однако, удалит все найденные вхождения, а не только первое
Flavien Volken

4
И он вернет новый массив вместо изменения исходного. В зависимости от варианта использования, это может или не может быть то, что вы хотите.
Джочи Набуурс

1
@JochieNabuurs это действительно новый массив. Однако объект остается прежним. Вы все еще можете изменить значение каждого объекта, и оно отразится на объекте исходного массива.
DriLLFreAK100

2
Кстати, об этом, возвращая новый массив, просто меняя решение на someArray = someArray.filter(function(el) { return el.Name != "Kristian"; }); адреса, которые нет?
hBrent

93

Как насчет этого?

$.each(someArray, function(i){
    if(someArray[i].name === 'Kristian') {
        someArray.splice(i,1);
        return false;
    }
});

8
Не приведет ли это к ошибке, потому что $.each()кеширует длину массива перед циклом, поэтому, если вы удалите элемент, он $.each()будет проходить после конца (теперь более короткого) массива. (Так что тогда someArray[i]будет undefinedи undefined.nameрухнет.)
nnnnnn

5
Затем добавьте «return false» после сращивания.
Аллан Тейлор

18
это не JavaScript -1
луковица

20
Обратите внимание, что для ответа на этот вопрос требуется jQuery
Clarkey

68

Ваш "массив", как показано, имеет неверный синтаксис JavaScript. Фигурные скобки {}предназначены для объектов с парами имя / значение свойства, а квадратные скобки []- для массивов, например:

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

В этом случае вы можете использовать .splice()метод для удаления элемента. Чтобы удалить первый элемент (индекс 0), скажите:

someArray.splice(0,1);

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

Если вы не знаете индекс, но хотите выполнить поиск в массиве, чтобы найти элемент с именем «Kristian», вы можете удалить это:

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

РЕДАКТИРОВАТЬ: я только что заметил, что ваш вопрос помечен как «jQuery», так что вы можете попробовать $.grep()метод :

someArray = $.grep(someArray,
                   function(o,i) { return o.name === "Kristian"; },
                   true);

Почему они добавили перегрузку? Конечно, вы могли бы просто положить! = "Кристиан". Какой цели служит перегрузка?
markthewizard1234

@ markthewizard1234 - Вы имеете в виду логический аргумент «инвертировать» $.grep()? Это мало что добавляет в этом примере, где да, я мог бы поставить !=, но в других случаях у вас уже может быть определена функция, которая выполняет противоположный тест по отношению к тому, что вы хотите выполнить grep, так что вместо определения Дополнительная функция, которую вы можете просто использовать эту перегрузку, чтобы инвертировать результаты.
nnnnnn

Ах, так что если у вас есть функция-обертка, содержащая grep, вы можете установить логическое значение в качестве параметра. Понял, спасибо!
markthewizard1234

@ markthewizard1234 - Можно, но я не это имел в виду: представьте, что вы имели в виду function isEven(num) { return num%2===0 }. Вы можете использовать, $.grep(someArray, isEven)чтобы получить только четные числа из массива, или $.grep(someArray, isEven, true)сделать наоборот и получить нечетные значения.
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');

Это удалит Джона !


4
Человек ... Исходя из Java, я сильно смущен, что такая простая вещь, которую нужно сделать, требует фильтрации списка ... WTF. Это самый точный ответ на вопрос ОП, который я когда-либо читал.
codepleb

Да, это хороший подход. Хотя это также будет работать до ES2015 (ES6). Функция фильтра доступна с версии 5.1 (2011) ecma-international.org/ecma-262/5.1/#sec-15.4.4.20
user3777549

40

Вы можете использовать array.filter ().

например

        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"}];

Функции стрелок:

someArray = someArray.filter(x => x.name !== 'Kristian')

Еще одна вещь, которую я хочу, будут отдельные кнопки для каждого объекта в массиве. если я хочу удалить этот конкретный объект в кнопке массива нажал. как это сделать . Я использовал угловой JS NG-повтор для создания предметов. Вы можете мне помочь
Тилак Радж

daCoda, что если у вас есть два условия?
Малкольм Сальвадор

@MalcolmSalvador скажем, например, если у вас есть другие условия, вы можете написать это, как показано ниже, и продолжить с другими && или || Оператор в соответствии с вашими потребностями. someArray = someArray.filter (function (returnableObjects) {return returnableObjects.name! == 'Kristian' && cond2Query.age> = 22;});
Biswajit Panday

18

Я сделал динамическую функцию, принимает объекты Array, Key и value и возвращает тот же массив после удаления нужного объекта:

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

        }

Полный пример: ДЕМО

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"));

15

Это функция, которая работает для меня:

function removeFromArray(array, value) {
    var idx = array.indexOf(value);
    if (idx !== -1) {
        array.splice(idx, 1);
    }
    return array;
}

Еще одна вещь, которую я хочу, будут отдельные кнопки для каждого объекта в массиве. если я хочу удалить этот конкретный объект в кнопке массива нажал. как это сделать . Я использовал угловой JS NG-повтор для создания предметов. Вы можете мне помочь
Тилак Радж

12

Вы также можете попробовать сделать что-то вроде этого:

var myArray = [{'name': 'test'}, {'name':'test2'}];
var myObject = {'name': 'test'};
myArray.splice(myArray.indexOf(myObject),1);


10

Используйте функцию сплайсинга на массивах. Укажите позицию начального элемента и длину подпоследовательности, которую вы хотите удалить.

someArray.splice(pos, 1);


4

С функцией стрелки 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)

3

Простейшим решением было бы создать карту, в которой хранятся индексы для каждого объекта по имени, например:

//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 );

Мне нравится эта идея, но я также должен спросить, каковы пределы использования памяти для такой идеи при добавлении индексов? У меня есть массив, который я хотел бы проиндексировать на 2 разных полях объекта, поэтому у меня было бы 2 карты в дополнение к исходному массиву источника. Это небольшая цена за скорость поиска или есть решение, которое будет более эффективным с памятью?
Брэд Г.

3

Хотя это, вероятно, не совсем подходит для этой ситуации, я узнал на днях, что вы также можете использовать deleteключевое слово, чтобы удалить элемент из массива, если вам не нужно изменять размер массива, например

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

3

Этот ответ

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

не работает для нескольких записей, удовлетворяющих условию. Если у вас есть две такие последовательные записи, удаляется только первая, а другая пропускается. Вы должны использовать:

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

вместо.


2

Кажется, в синтаксисе вашего массива есть ошибка, поэтому, если вы имеете в виду массив, а не объект, Array.splice ваш друг здесь:

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

2

Вы также можете использовать функцию карты .

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);

1
Но если вы хотите перебрать массив, не лучше ли использовать forEach?
corse32

2

Вы также можете использовать 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) 
})

2

Это то, что я использую.

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();
  }

Тогда это так же просто, как сказать

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

Замените любое число вместо трех. После ожидаемого выхода должно быть:

console.log(myArray); //Expected output 1,2,3,5,6,7,8,9

2

Если вы хотите удалить все вхождения данного объекта (на основе какого-либо условия), используйте метод соединения javascript внутри цикла for.

Поскольку удаление объекта повлияет на длину массива, обязательно уменьшите счетчик на один шаг, чтобы проверка длины осталась без изменений.

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.
  }
}

Приведенный выше фрагмент кода удаляет все объекты, возраст которых превышает 20 лет.



1

splice (i, 1) где i - инкрементный индекс массива, удалит объект. Но помните, что сплайс также сбрасывает длину массива, так что следите за «неопределенным». Используя ваш пример, если вы удалите «Kristian», то при следующем выполнении в цикле у меня будет 2, а someArray будет иметь длину 1, поэтому, если вы попытаетесь удалить «John», вы получите ошибку «undefined» , Одним из решений этого, хотя и не элегантного, является наличие отдельного счетчика для отслеживания индекса удаляемого элемента.


1

Возвращает только объекты из массива, свойство nameкоторых не "Kristian"

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


Демо-версия:

 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>


0

Это концепции с использованием кендо сетки

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

var selectedItem = SelectedCheckBoxList;

for (var i = 0; i < selectedItem.length; i++) {
    if(selectedItem[i].boolKendoValue==true)
    {
        selectedItem.length= 0;
    }
}

0

Я думаю, что ответы очень разветвлены и завязаны.

Вы можете использовать следующий путь для удаления объекта массива, который соответствует объекту, данному в современном жаргоне JavaScript.


coordinates = [
    { lat: 36.779098444109145, lng: 34.57202827508546 },
    { lat: 36.778754712956506, lng: 34.56898128564454 },
    { lat: 36.777414146732426, lng: 34.57179224069215 }
];

coordinate = { lat: 36.779098444109145, lng: 34.57202827508546 };

removeCoordinate(coordinate: object) {
  const found = this.coordinates.find((obj) => obj === obj);
  if (found) {
    this.coordinates.splice(found, 1);
  }
}

this.removeCoordinate(coordinate);

-2

Если вы хотите получить доступ и удалить объект массива просто, вы можете попробовать что-то вроде этого.

// 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 }];
        

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.