Як видалити елемент масиву в TypeScript?


404

У мене є масив, який я створив у TypeScript, і він має властивість, яку я використовую як ключ. Якщо у мене є цей ключ, як я можу видалити з нього предмет?

Відповіді:


639

Так само, як і в JavaScript.

delete myArray[key];

Зауважте, що це встановлює елемент undefined .

Краще використовувати Array.prototype.spliceфункцію:

const index = myArray.indexOf(key, 0);
if (index > -1) {
   myArray.splice(index, 1);
}

8
Ви можете додати тип до цього! var index: number = myArray.indexOf(key, 0);
CorayThan

17
@CorayThan Безумовно, це буде неявно введено як indexOfповернення number?
Кріс

5
@Chris Хоча це очевидно в цьому простому випадку, він може допомогти вам швидше діагностувати помилки, якщо чітко визначити тип для кожної змінної. Ви вже indexне раз використовуєте місце, і одне з цих місць ( splice) хоче побачити номер, або ви отримаєте помилку. Наразі компілятор не може перешкодити вам помилитися там.
Йохім Куджперс

33
@blorkfish добре згадати, що якщо у вас є список об'єктів, ви можете використовувати var index = myArray.findIndex(x => x.prop==key.prop);.
Франциско Кабрал

6
@ Cirelli94 - ви відповідаєте на більш старий потік, але відповідь на ваше запитання полягає в тому, що видалення елемента масиву не змінює його довжину або переіндексує масив. Оскільки масиви є об'єктами в JavaScript, delete myArr[2]буквально видаляє властивість 2 з myArr, яке також відрізняється myArr[2] = undefined. Мораль цієї історії полягає в тому, щоб просто використовувати spliceдля цього завдання, оскільки це безпечний спосіб отримати бажаний ефект, не плутаючи побічні ефекти.
winglerw28

200

Якщо масив - це тип об’єктів, то це найпростіший спосіб

let foo_object // Item to remove
this.foo_objects = this.foo_objects.filter(obj => obj !== foo_object);

20
Це не видаляє нічого, воно просто фільтрується. Якщо список насправді потрібно змінити, це не спосіб.
користувач573434

6
@ user573434 так, ви праві, як вказує назва. Але це простий підхід у випадку, коли ви хочете видалити об'єкт при успішному видаленні api-дзвінка тощо.
Malik Shahzad

3
Це прекрасно працювало для мене на масиві об'єктів без унікальної ключової властивості. @ user573434 метод фільтра повертає новий масив без відфільтрованого об'єкта, тому отриманий масив об'єкт видалено.
Джейсон

6
я думаю, щоб повернути його як об’єкт, ти повинен це зробитиthis.foo_objects = this.foo_objects.filter(obj => obj !== foo_object)[0];
Roel

1
Це працює. просто уважно прочитайте 2-й рядок. він робить фільтр з obj! = foo_object. і призначає його до вихідної змінної, замінюючи таким чином вихідний масив на один мінус відфільтрованого foo_object. використовували його з масивом об’єктів з id deleteById(id: string) { this.data = this.data.filter(d => d.id !== id); }Просто одне слово попередження, якщо ID-коди не унікальні, ви видалите все те самеid
Markus

74

За допомогою ES6 ви можете використовувати цей код:

removeDocument(doc){
   this.documents.forEach( (item, index) => {
     if(item === doc) this.documents.splice(index,1);
   });
}

1
Найкраще рішення для видалення без зміни посилання масиву І з можливістю впровадження конкретної алгоритму рівності
Sid

1
Найкращу відповідь знайшли
Gvs Akhil

1
Найкраща відповідь, якщо використовувати ES6
Натан Бек

2
Ви також можете використовувати: this.documents.forEach ((елемент, індекс, масив) => {if (item === doc) array.splice (index, 1);}); Що може бути набагато чистішим, особливо при роботі з вкладеними масивами.
CGundlach

20

Це моє рішення для цього:

onDelete(id: number) {
    this.service.delete(id).then(() => {
        let index = this.documents.findIndex(d => d.id === id); //find index in your array
        this.documents.splice(index, 1);//remove element from array
    });

    event.stopPropagation();
}

Що приємного в цьому рішенні - це те, що воно буде працювати навіть тоді, коли рівність об'єктів не зможе визначити два об'єкти як рівні.
Бред Джонсон

18

Ви можете використовувати spliceметод на масиві для видалення елементів.

наприклад, якщо у вас є масив з іменем, arrвикористовуйте наступне:

arr.splice(2, 1);

тому тут елемент з індексом 2 буде початковою точкою, а аргумент 2 визначатиме, скільки елементів потрібно видалити.

Якщо ви хочете видалити останній елемент з імені масиву, arrзробіть це:

arr.splice(arr.length-1, 1);

Це поверне arr з останнім елементом, видаленим.

Приклад:

var arr = ["orange", "mango", "banana", "sugar", "tea"];
arr.splice(arr.length-1, 1)
console.log(arr); // return ["orange", "mango", "banana", "sugar"]

1
Просто FYI, метод сплайсингу модифікує масив (тому в цьому випадку видаляє останній елемент) і повертає видалені елементи (а), а не сам масив.
CGundlach

2
Фактично має бути arr.splice (arr.length-1,1) для видалення останнього елемента.
Стів В СО

15

нехай відділи - це масив. Ви хочете видалити елемент з цього масиву.

departments: string[] = [];

 removeDepartment(name: string): void {
    this.departments = this.departments.filter(item => item != name);
  }

8

Ось простий один вкладиш для видалення об'єкта за властивістю з масиву об’єктів.

delete this.items[this.items.findIndex(item => item.item_id == item_id)];

або

this.items = this.items.filter(item => item.item_id !== item.item_id);

1
Проблема першого рішення полягає в тому, що delete видаляє елемент, але розмір масиву залишається таким же, як і до вилучення. У другому рішенні у нас буде новий об'єкт, тому якщо ми маємо залежність від спаму, то ми втрачаємо його. Сплайс (який знаходиться у верхній відповіді) не має цього ефекту.
Krystian

Дякуємо, що вказали на це. Я думаю, що у своєму випадку використання я цього ще не виявив. Добре спостерігається :)
Джеймі

5

Відповідь за допомогою оператора розширення TypeScript (...)

// Your key
const key = 'two';

// Your array
const arr = [
    'one',
    'two',
    'three'
];

// Get either the index or -1
const index = arr.indexOf(key); // returns 0


// Despite a real index, or -1, use spread operator and Array.prototype.slice()    
const newArray = (index > -1) ? [
    ...arr.slice(0, index),
    ...arr.slice(index + 1)
] : arr;

5

Ще одне рішення за допомогою Typescript:

let updatedArray = [];
for (let el of this.oldArray) {
    if (el !== elementToRemove) {
        updated.push(el);
    }
}
this.oldArray = updated;

Хоча це і вирішує задану проблему, її виконати дорого через створення нового масиву та перекидання на оригінал. Виконання подібних операцій на величезному масиві може призвести до небажаних побічних ефектів, таких як, важче для мобільних батарей, тривалого очікування, вибивання тощо.
Jessy

1

Використовуйте це, якщо вам потрібно видалити заданий об'єкт із масиву, і ви хочете бути впевнені в наступному:

  • список не повторно реалізується
  • довжина масиву належним чином оновлена
    const objWithIdToRemove;
    const objIndex = this.objectsArray.findIndex(obj => obj.id === objWithIdToRemove);
    if (objIndex > -1) {
      this.objectsArray.splice(objIndex, 1);
    }

0

Просто хотів додати метод розширення для масиву.

interface Array<T> {
      remove(element: T): Array<T>;
    }

    Array.prototype.remove = function (element) {
      const index = this.indexOf(element, 0);
      if (index > -1) {
        return this.splice(index, 1);
      }
      return this;
    };
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.