Câu hỏi Xóa các phần tử mảng trong JavaScript - xóa so với mối nối


Sự khác biệt giữa việc sử dụng các delete nhà điều hành trên phần tử mảng trái ngược với việc sử dụng các Array.splice phương pháp?

Ví dụ:

myArray = ['a', 'b', 'c', 'd'];

delete myArray[1];
//  or
myArray.splice (1, 1);

Tại sao thậm chí có phương pháp ghép nối nếu tôi có thể xóa các phần tử mảng như tôi có thể với các đối tượng?


1177
2018-02-01 11:11


gốc


Dành cho .splice trong vòng lặp, hãy xem câu hỏi này: Xóa khỏi mảng trong javascript. - Rob W
@andynormancx Có, nhưng câu trả lời này đã được đăng lên chỉ một ngày sau đó, và đã nhận được nhiều phiếu bầu hơn nữa - tôi muốn nói nó tốt hơn bằng văn bản, đó phải là nó. - Camilo Martin
@andynormancx - Có vẻ như đó không phải là bản sao chính xác. Câu hỏi bạn đã liên kết về cơ bản là hỏi lý do xóa một phần tử khỏi mảng (do đó làm cho nó thưa thớt) sẽ không làm giảm độ dài của nó. Câu hỏi này yêu cầu sự khác biệt giữa delete và Array.prototype.splice. - chharvey
@chharvey đồng ý, quan trọng hơn mặc dù làm thế nào câu hỏi này đã được đăng 9 năm trước đây! Làm cho tôi cảm thấy cũ để trở lại đây bình luận về nó - andynormancx


Các câu trả lời:


delete sẽ xóa thuộc tính đối tượng, nhưng sẽ không reindex mảng hoặc cập nhật độ dài của nó. Điều này làm cho nó xuất hiện như thể nó không được xác định:

> myArray = ['a', 'b', 'c', 'd']
  ["a", "b", "c", "d"]
> delete myArray[0]
  true
> myArray[0]
  undefined

Lưu ý rằng thực tế không được đặt thành giá trị undefined, thay vào đó thuộc tính bị xóa khỏi mảng, làm cho nó xuất hiện chưa xác định. Các công cụ của Chrome dev giúp phân biệt rõ ràng bằng cách in empty khi đăng nhập mảng.

> myArray[0]
  undefined
> myArray
  [empty, "b", "c", "d"]

myArray.splice(start, deleteCount) thực sự loại bỏ phần tử, reindexes mảng và thay đổi độ dài của nó.

> myArray = ['a', 'b', 'c', 'd']
  ["a", "b", "c", "d"]
> myArray.splice(0, 2)
  ["a", "b"]
> myArray
  ["c", "d"]

1542
2018-02-01 11:16



sửa cho dòng 3: [undefined, 'b', 'c', 'd'] (nó không phải là chuỗi 'undefined', nhưng giá trị đặc biệt không xác định) - Jasper
Thực ra, delete  làm loại bỏ các phần tử, nhưng không reindex mảng hoặc cập nhật chiều dài của nó (mà đã được ngụ ý bởi các cựu kể từ khi chiều dài luôn luôn là chỉ số cao nhất + 1). - Felix Kling
JSlint không thích delete myArray[0] cú pháp nói "Dự kiến ​​một nhà điều hành và thay vào đó thấy 'xóa'."Sử dụng splice được khuyến nghị. - Eye
@Eye: Thực ra, JSLint chỉ phàn nàn về việc thiếu dấu chấm phẩy trên dòng trước đó. Và bạn thực sự không thể giới thiệu cái này với nhau, vì chúng hoàn toàn khác nhau… - Ry-♦
"Xóa trong trường hợp này sẽ chỉ đặt phần tử là chưa được xác định:" Không, đó là không chính xác. Có một sự khác biệt cơ bản giữa delete myArray[0] và myArray[0] = undefined. Trong trường hợp trước đây, thuộc tính được loại bỏ hoàn toàn khỏi đối tượng mảng. Trong trường hợp thứ hai, tài sản vẫn còn, với giá trị undefined. - T.J. Crowder


Phương thức Array.remove ()

John Resig, người sáng tạo jQuery tạo ra một tiện ích rất tiện dụng Array.remove phương pháp mà tôi luôn sử dụng nó trong các dự án của mình.

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

và đây là một số ví dụ về cách nó có thể được sử dụng:

// Remove the second item from the array
array.remove(1);
// Remove the second-to-last item from the array
array.remove(-2);
// Remove the second and third items from the array
array.remove(1,2);
// Remove the last and second-to-last items from the array
array.remove(-2,-1);

Trang web của John


321
2018-03-22 00:51



+1 Đối với Array.remove (). Tuy nhiên nó không phải là hạnh phúc được thông qua đối số chuỗi (không giống như hầu hết các phương pháp Array, ví dụ [1,2,3].slice('1'); // =[2,3]), vì vậy sẽ an toàn hơn khi thay đổi nó thành var rest = this.slice(parseInt(to || from) + 1 || this.length); - Richard Inglis
@tomwrong, không có chủ đề nào trong javascript và hàm thực thi this.push.apply(this, rest), sau đó trả về giá trị trả về - billy
Điều này không trả lời được câu hỏi nào cả. - Ry-♦
Tại sao không chỉ sử dụng mối nối ()? Tên của hàm này, tên tham số và kết quả không rõ ràng. Đề xuất của tôi là chỉ sử dụng mối nối (chỉ mục, độ dài) - (xem câu trả lời của Andy Hume) - auco
Chức năng được cung cấp ở trên các công trình như đã giải thích, nhưng nó tạo ra các tác dụng phụ không mong muốn khi lặp qua mảng với for(var i in array) chu kỳ. Tôi đã gỡ bỏ nó và sử dụng mối nối thay thế. - alexykot


Vì xóa chỉ xóa đối tượng khỏi phần tử trong mảng, độ dài của mảng sẽ không thay đổi. Splice loại bỏ đối tượng và rút ngắn mảng.

Đoạn mã sau sẽ hiển thị "a", "b", "undefined", "d"

myArray = ['a', 'b', 'c', 'd']; delete myArray[2];

for (var count = 0; count < myArray.length; count++) {
    alert(myArray[count]);
}

Trong khi điều này sẽ hiển thị "a", "b", "d"

myArray = ['a', 'b', 'c', 'd']; myArray.splice(2,1);

for (var count = 0; count < myArray.length; count++) {
    alert(myArray[count]);
}

95
2018-02-01 11:13



ví dụ tuyệt vời ngoại trừ sự mơ hồ trong ví dụ thứ hai bằng cách sử dụng 1,1 - đầu tiên 1 đề cập đến chỉ mục trong mảng để bắt đầu mối nối, số thứ hai là số phần tử cần xóa. Vì vậy, để loại bỏ 'c' từ mảng ban đầu, sử dụng myArray.splice(2,1) - iancoleman


Tôi vấp vào câu hỏi này trong khi cố gắng hiểu cách loại bỏ mọi sự xuất hiện của một phần tử từ một Mảng. Đây là một so sánh của splice và delete để loại bỏ mọi 'c' từ items Mảng.

var items = ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'];

while (items.indexOf('c') !== -1) {
  items.splice(items.indexOf('c'), 1);
}

console.log(items); // ["a", "b", "d", "a", "b", "d"]

items = ['a', 'b', 'c', 'd', 'a', 'b', 'c', 'd'];

while (items.indexOf('c') !== -1) {
  delete items[items.indexOf('c')];
}

console.log(items); // ["a", "b", undefined, "d", "a", "b", undefined, "d"]
​

60
2018-05-09 13:25



hướng dẫn rất hữu ích cho tôi. Cảm ơn trước... - Cataclysm


Từ  Tham khảo JavaScript JavaScript 1.5> Toán tử> Toán tử đặc biệt> Toán tử xóa :

Khi bạn xóa một phần tử mảng,   chiều dài mảng không bị ảnh hưởng. Dành cho   ví dụ: nếu bạn xóa [3], [4] là   vẫn còn [4] và [3] là không xác định. Điều này   giữ ngay cả khi bạn xóa   phần tử của mảng (xóa   a [a.length-1]).


13
2018-02-01 11:16





splice sẽ làm việc với các chỉ số số.

trong khi delete có thể được sử dụng chống lại các loại chỉ mục khác ..

thí dụ:

delete myArray['text1'];

9
2018-01-11 07:52



Khi bạn nói 'bất kỳ loại chỉ số nào khác', bạn không nói về mảng nữa, mà là đối tượng, đó là những gì mà OP đang hỏi. - Yi Jiang
@YiJiang: Mảng là đối tượng. Indizes là các thuộc tính. Không có sự khác biệt. - Bergi


Nó có lẽ cũng đáng nói đến là mối nối chỉ hoạt động trên các mảng. (Thuộc tính đối tượng không thể dựa vào để tuân theo một thứ tự nhất quán.)

Để xóa cặp khóa-giá trị khỏi đối tượng, xóa thực sự là những gì bạn muốn:

delete myObj.propName;     // , or:
delete myObj["propName"];  // Equivalent.

9
2017-08-01 20:11



xóa không sắp xếp lại các khóa mảng, vì vậy: var arr = [1,2,3,4,5]; xóa arr [3]; cho (var i = 0; i <= arr.length; i ++) console.log (arr [i]); sẽ hiển thị kết quả không mong muốn. - Kristian Williams
Điều này đúng. Vì vậy, trừ khi bạn muốn để lại một mục không xác định tại vị trí đó, KHÔNG sử dụng xóa trên các phím của một mảng! Ban đầu, tôi đã thêm nhận xét này để bao gồm tham chiếu về việc sử dụng xóa chính xác. - jtrick


xóa bỏ hoạt động như một tình huống không thực tế, nó chỉ loại bỏ mục, nhưng chiều dài mảng vẫn như cũ:

ví dụ từ thiết bị đầu cuối nút:

> var arr = ["a","b","c","d"];
> delete arr[2]
true
> arr
[ 'a', 'b', , 'd', 'e' ]

Đây là một hàm để loại bỏ một mục của một mảng theo chỉ mục, bằng cách sử dụng slice (), nó lấy arr là arg đầu tiên và chỉ mục của thành viên mà bạn muốn xóa làm đối số thứ hai. Như bạn có thể thấy, nó thực sự xóa thành viên của mảng và sẽ giảm độ dài mảng xuống 1

function(arr,arrIndex){
    return arr.slice(0,arrIndex).concat(arr.slice(arrIndex + 1));
}

Hàm trên làm cho tất cả các thành viên lên đến chỉ mục và tất cả các thành viên sau chỉ mục và nối chúng lại với nhau và trả về kết quả.

Dưới đây là một ví dụ bằng cách sử dụng hàm ở trên làm mô-đun nút, nhìn thấy thiết bị đầu cuối sẽ hữu ích:

> var arr = ["a","b","c","d"]
> arr
[ 'a', 'b', 'c', 'd' ]
> arr.length
4 
> var arrayRemoveIndex = require("./lib/array_remove_index");
> var newArray = arrayRemoveIndex(arr,arr.indexOf('c'))
> newArray
[ 'a', 'b', 'd' ] // c ya later
> newArray.length
3

xin lưu ý rằng điều này sẽ không làm việc một mảng với dupes trong nó, bởi vì indexOf ("c") sẽ chỉ nhận được sự xuất hiện đầu tiên, và chỉ ghép ra và loại bỏ đầu tiên "c" nó tìm thấy.


7
2017-07-20 02:20





Như đã nói nhiều lần ở trên, sử dụng splice() có vẻ như hoàn toàn phù hợp. Tài liệu tại Mozilla:

Các splice() phương pháp thay đổi nội dung của một mảng bằng cách loại bỏ các phần tử hiện có và / hoặc thêm các phần tử mới.

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];

myFish.splice(2, 0, 'drum'); 
// myFish is ["angel", "clown", "drum", "mandarin", "sturgeon"]

myFish.splice(2, 1); 
// myFish is ["angel", "clown", "mandarin", "sturgeon"]

Cú pháp

array.splice(start)
array.splice(start, deleteCount)
array.splice(start, deleteCount, item1, item2, ...)

Thông số

khởi đầu

Chỉ mục để bắt đầu thay đổi mảng. Nếu lớn hơn độ dài của mảng, chỉ số bắt đầu thực tế sẽ được đặt thành độ dài của mảng. Nếu tiêu cực, sẽ bắt đầu có nhiều yếu tố từ cuối.

deleteCount

Một số nguyên cho biết số phần tử mảng cũ cần xóa. Nếu deleteCount là 0, không có phần tử nào bị xóa. Trong trường hợp này, bạn nên chỉ định ít nhất một phần tử mới. Nếu deleteCount lớn hơn số phần tử còn lại trong mảng bắt đầu lúc bắt đầu, thì tất cả các phần tử thông qua phần cuối mảng sẽ bị xóa.

Nếu deleteCount bị bỏ qua, deleteCount sẽ bằng (arr.length - start).

mục 1, mục 2, ...

Các phần tử để thêm vào mảng, bắt đầu từ chỉ mục bắt đầu. Nếu bạn không chỉ định bất kỳ phần tử nào, splice() sẽ chỉ xóa các phần tử khỏi mảng.

Giá trị trả về

Một mảng chứa các phần tử đã xóa. Nếu chỉ có một phần tử bị xóa, một mảng của một phần tử được trả về. Nếu không có phần tử nào bị xóa, một mảng trống sẽ được trả về.

[...]


7
2018-01-08 10:43



@ downvoter: tại sao downvote? quan tâm để giải thích, hay không? - serv-inc