Làm cách nào để xóa một mục mảng trong TypeScript?


405

Tôi có một mảng mà tôi đã tạo trong TypeScript và nó có một thuộc tính mà tôi sử dụng làm khóa. Nếu tôi có chìa khóa đó, làm thế nào tôi có thể xóa một mục khỏi nó?

Câu trả lời:


640

Tương tự như cách bạn làm trong JavaScript.

delete myArray[key];

Lưu ý rằng điều này đặt thành phần undefined.

Tốt hơn để sử dụng Array.prototype.splicechức năng:

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

8
Bạn có thể thêm một loại để đó! var index: number = myArray.indexOf(key, 0);
CorayThan

17
@CorayThan Chắc chắn nó sẽ được gõ ngầm là indexOftrả về a number?
Chris

5
@Chris Mặc dù rõ ràng trong trường hợp đơn giản này, nó có thể giúp bạn chẩn đoán lỗi nhanh hơn nếu bạn xác định rõ ràng một loại cho mỗi biến. Bạn đang sử dụng indexở nhiều nơi hơn một lần và một trong những nơi đó ( splice) muốn xem số hoặc bạn sẽ gặp lỗi. Hiện tại trình biên dịch không thể ngăn bạn mắc lỗi ở đó.
Joool Kuijpers

33
@blorkfish thật tốt khi đề cập rằng nếu bạn có một danh sách các đối tượng, bạn có thể sử dụng var index = myArray.findIndex(x => x.prop==key.prop);.
Francisco Cabral

6
@ Cirelli94 - bạn đang trả lời một chủ đề cũ hơn, nhưng câu trả lời cho câu hỏi của bạn là việc xóa một phần tử mảng không thay đổi độ dài của nó hoặc lập chỉ mục lại mảng. Bởi vì mảng là các đối tượng trong JavaScript, theo delete myArr[2]nghĩa đen sẽ xóa thuộc tính 2 của myArr, điều này cũng khác với myArr[2] = undefined. Đạo đức của câu chuyện này là chỉ sử dụng splicecho nhiệm vụ này bởi vì đây là một cách an toàn để có được hiệu quả mong muốn mà không gây nhầm lẫn tác dụng phụ.
winglerw28

200

Nếu mảng là loại đối tượng, thì cách đơn giản nhất là

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

20
Điều này không loại bỏ bất cứ thứ gì nó chỉ đơn giản là bộ lọc. Nếu danh sách thực sự cần phải sửa đổi thì đây không phải là cách.
dùng573434

6
@ user573434 có, bạn đúng, như tên cho biết. Nhưng đây là cách tiếp cận đơn giản trong trường hợp bạn muốn xóa một đối tượng khi xóa cuộc gọi api thành công, v.v.
Malik Shahzad

3
Điều này làm việc hoàn hảo cho tôi trên một loạt các đối tượng mà không có thuộc tính khóa duy nhất. @ user573434 phương thức bộ lọc trả về một mảng mới mà không có đối tượng được lọc, vì vậy mảng kết quả sẽ loại bỏ đối tượng.
Jason

6
tôi nghĩ để trả lại nó như một đối tượng bạn phải làm điều nàythis.foo_objects = this.foo_objects.filter(obj => obj !== foo_object)[0];
Roel

1
Những công việc này. chỉ cần đọc kỹ dòng 2 anh ấy thực hiện một bộ lọc với obj! = foo_object. và gán nó cho biến ban đầu, do đó thay thế mảng ban đầu bằng một trừ foo_object được lọc. đã sử dụng nó với một loạt các đối tượng có id deleteById(id: string) { this.data = this.data.filter(d => d.id !== id); }Chỉ cần một từ cảnh báo, nếu Id không phải là duy nhất, bạn sẽ xóa tất cả bằng cùngid
Markus

74

Với ES6, bạn có thể sử dụng mã này:

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

1
Giải pháp tốt nhất để loại bỏ mà không thay đổi tham chiếu mảng VÀ có khả năng thực hiện đại số bình đẳng cụ thể
Sid

1
Câu trả lời hay nhất đã được tìm thấy
Gvs Akhil

1
Câu trả lời tốt nhất nếu sử dụng ES6
Nathan Beck

2
Bạn cũng có thể sử dụng: this.document.forEach ((item, index, mảng) => {if (item === doc) Array.splice (index, 1);}); Mà có thể sạch hơn rất nhiều, đặc biệt là khi làm việc với các mảng lồng nhau.
CGundlach

20

Đó là giải pháp của tôi cho điều đó:

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

Điều tuyệt vời về giải pháp này là nó sẽ hoạt động ngay cả khi bình đẳng đối tượng không xác định hai đối tượng là bằng nhau.
Brad Johnson

18

Bạn có thể sử dụng splicephương thức trên một mảng để loại bỏ các phần tử.

ví dụ: nếu bạn có một mảng với tên, hãy arrsử dụng như sau:

arr.splice(2, 1);

vì vậy ở đây phần tử có chỉ số 2 sẽ là điểm bắt đầu và đối số 2 sẽ xác định có bao nhiêu phần tử sẽ bị xóa.

Nếu bạn muốn xóa phần tử cuối cùng của mảng có tên arrthì hãy làm điều này:

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

Điều này sẽ trả về mảng với phần tử cuối cùng bị xóa.

Thí dụ:

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

1
Chỉ cần FYI, phương thức mối nối sửa đổi mảng (vì vậy trong trường hợp này sẽ loại bỏ mục cuối cùng) và trả về (các) mục đã xóa, chứ không phải chính mảng đó.
CGundlach

2
Nó thực sự phải là Array.splice (Array.length-1,1) để loại bỏ phần tử cuối cùng.
Steve In CO

15

hãy để các phòng ban là một mảng. Bạn muốn loại bỏ một mục từ mảng này.

departments: string[] = [];

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

8

Đây là một lớp lót đơn giản để loại bỏ một đối tượng theo thuộc tính khỏi một mảng các đối tượng.

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

hoặc là

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

1
Vấn đề với giải pháp đầu tiên là xóa bỏ phần tử, nhưng kích thước mảng vẫn giữ nguyên như trước khi tháo gỡ. Trong giải pháp thứ hai, chúng ta sẽ có một đối tượng mới, vì vậy nếu chúng ta có sự phụ thuộc spme thì chúng ta sẽ mất nó. Splice (nằm trong câu trả lời hàng đầu) không có hiệu ứng này.
Kirtian

Cảm ơn đã chỉ ra rằng. Tôi nghĩ rằng trong trường hợp sử dụng của tôi, tôi đã không phát hiện ra điều đó. Quan sát tốt :)
Jamie Armor

5

Trả lời bằng toán tử trải rộng 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

Thêm một giải pháp sử dụng Bản mô tả:

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

Trong khi điều này không giải quyết được vấn đề được yêu cầu, nó rất tốn kém để thực thi do việc tạo ra một mảng mới và lặp lại so với bản gốc. Thực hiện loại hoạt động này trên một mảng lớn có thể tạo ra các tác dụng phụ không mong muốn như, khó hơn đối với pin di động, chờ đợi lâu, jank, v.v.
Jessy

1

Sử dụng cái này, nếu bạn cần xóa một đối tượng đã cho khỏi một mảng và bạn muốn chắc chắn về những điều sau đây:

  • danh sách không được khởi tạo lại
  • chiều dài mảng được cập nhật đúng
    const objWithIdToRemove;
    const objIndex = this.objectsArray.findIndex(obj => obj.id === objWithIdToRemove);
    if (objIndex > -1) {
      this.objectsArray.splice(objIndex, 1);
    }

0

Chỉ muốn thêm phương thức mở rộng cho một mảng.

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;
    };
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.