Xóa đối tượng khỏi mảng bằng JavaScript


549

Làm thế nào tôi có thể loại bỏ một đối tượng từ một mảng? Tôi muốn xóa đối tượng bao gồm tên Kristiantừ someArray. Ví dụ:

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

Tôi muốn đạt được:

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


3
FYI Tôi đã khôi phục lại phần chỉnh sửa cho câu hỏi này để cú pháp mảng lại bị sai và tất cả các câu trả lời này đều nằm trong ngữ cảnh.
Dunhamzzz

2
Và sau đó cú pháp mảng được "sửa lại" (hai lần) một lần nữa, để các câu trả lời không còn trong ngữ cảnh.
Teepeemm

4
Làm thế nào để lỗi cú pháp giúp làm cho một số câu trả lời có ý nghĩa?
Samy Bencherif

1
@SamyBencherif - Một số câu trả lời giải quyết rõ ràng lỗi cú pháp trong phiên bản gốc của câu hỏi, vì vậy nếu bạn xóa lỗi cú pháp đó, các câu trả lời hiện đang nói về điều gì đó không tồn tại.
nnnnnn

Câu trả lời:


778

Bạn có thể sử dụng một số phương pháp để xóa (các) mục khỏi Mảng:

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

Nếu bạn muốn xóa phần tử tại vị trí x, sử dụng:

someArray.splice(x, 1);

Hoặc là

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

Trả lời nhận xét của @ chill182 : bạn có thể xóa một hoặc nhiều phần tử khỏi một mảng bằng cách sử dụng Array.filterhoặc Array.splicekết hợp với Array.findIndex(xem MDN ), ví dụ:

// 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
@Klemzy không có nghĩa là bạn không theo chỉ số? theo giá trị ...?
Royi Namir

328
Câu hỏi ban đầu hỏi làm thế nào để loại bỏ đối tượng có tên = "Kristian" khỏi mảng. Câu trả lời của bạn cho rằng đó là mục đầu tiên trong mảng nhưng nếu Kristin không có trong mục đầu tiên thì sao? Sau đó, câu trả lời của bạn không hoạt động.
Rochelle C

7
@ chill182: đó không phải là một câu trả lời cụ thể, mà là một câu trả lời tổng quát hơn. Từ đó, bạn sẽ có thể suy ra phương thức để loại bỏ các phần tử. Nếu bạn muốn xóa phần tử ở vị trí x ... có thể là một gợi ý để loại bỏ phần tử khác ngoài phần tử đầu tiên, phải không?
KooiInc

6
Hàm splice rất hữu ích với tôi, nhưng bạn không nên gán lại someArray. Điều này sẽ dẫn đến một sốArray chứa mục bị loại bỏ, thay vì nó chứa mảng kết quả với mục bị xóa.
Kenn Cal

1
Bạn nên kiểm tra findIndexkết quả trước khi sử dụng nó splice. Nếu không có phần tử nào trong mảng khớp với điều kiện findIndexsẽ trả về -1và đưa phần này trực tiếp vào splicesẽ dẫn đến việc xóa tùy ý phần tử cuối cùng trong mảng.
jdnz

131

Tôi khuyên bạn nên sử dụng lodash.js hoặc sugar.js cho các tác vụ phổ biến như thế này:

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

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

trong hầu hết các dự án, có một tập hợp các phương thức trợ giúp được cung cấp bởi các thư viện như thế này là khá hữu ích.


13
Tôi nghĩ rằng ví dụ gạch dưới là hơi tắt. Nên làsomeArray = _.reject(someArray, function(el) { return el.Name === "Kristian"; });
Andy Ford

7
Nếu bạn không muốn sử dụng underscore.js hoặc sugar.js, bạn có thể làm điều nàysomeArray = someArray.filter(function(e) { return e.Name !== "Kristian"; });
BenR

1
Một điều tôi muốn, Sẽ có các nút riêng biệt cho mọi đối tượng trong mảng. nếu tôi muốn xóa đối tượng cụ thể đó trong nút mảng đã nhấp. làm thế nào để làm nó . tôi đã sử dụng js ng-repeat góc để tạo ra các mục. bạn có thể giúp tôi không
Thilak Raj

5
Đi để chống lại hạt lúa ở đây; đề xuất một bao gồm toàn bộ thư viện cho mục đích đơn giản là loại bỏ các mục khỏi các đối tượng (mà js hỗ trợ rõ ràng ra khỏi hộp, vì câu trả lời được chấp nhận cho thấy) là hình thức kém. Nó thêm trọng lượng và độ phức tạp không cần thiết vào mã của bạn trừ khi bạn đã cần nó cho chức năng mạnh hơn mà thư viện cung cấp.
Josh Doebbert

4
Đối với hoạt động đơn giản, tôi sẽ không bao giờ đề nghị bao gồm thư viện
Munna Bhakta

130

Giải pháp sạch sẽ là sử dụng Array.filter:

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

Vấn đề với điều này là nó không hoạt động trên IE <9. Tuy nhiên, bạn có thể bao gồm mã từ thư viện Javascript (ví dụ underscore.js ) thực hiện điều này cho bất kỳ trình duyệt nào.


10
Tuy nhiên, điều này sẽ loại bỏ tất cả các lần xuất hiện, không chỉ lần đầu tiên
Flavien Volken

4
Và nó sẽ trả về một mảng mới thay vì sửa đổi bản gốc. Tùy thuộc vào trường hợp sử dụng, điều này có thể hoặc không thể là những gì bạn muốn.
Jochie Nabuurs

1
@JochieNabuurs nó thực sự là một mảng mới. Tuy nhiên, đối tượng vẫn giữ nguyên. Bạn vẫn có thể sửa đổi giá trị của từng đối tượng và nó sẽ phản ánh trên đối tượng của mảng ban đầu.
DriLLFreAK100

2
Đối với vấn đề này trả về một mảng mới, chỉ cần thay đổi giải pháp thành someArray = someArray.filter(function(el) { return el.Name != "Kristian"; }); địa chỉ đó, không?
hBrent

93

Còn cái này thì sao?

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

8
Sẽ không gây ra lỗi vì $.each()lưu trữ độ dài mảng trước khi lặp, vì vậy nếu bạn loại bỏ một phần tử $.each()sẽ chạy qua phần cuối của mảng (bây giờ ngắn hơn). (Vì vậy, sau đó someArray[i]sẽ undefinedundefined.namesẽ sụp đổ.)
nnnnnn

5
Sau đó thêm một 'return false' sau mối nối.
Allan Taylor

18
Đây không phải là javascript. -1
củ hành tây

20
Xin lưu ý rằng câu trả lời này yêu cầu jQuery
Clarkey

68

"Mảng" của bạn như được hiển thị là cú pháp JavaScript không hợp lệ. Dấu ngoặc nhọn {}dành cho các đối tượng có cặp tên / giá trị thuộc tính, nhưng dấu ngoặc vuông []dành cho mảng - như vậy:

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

Trong trường hợp đó, bạn có thể sử dụng .splice()phương pháp để xóa một mục. Để xóa mục đầu tiên (chỉ mục 0), hãy nói:

someArray.splice(0,1);

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

Nếu bạn không biết chỉ mục nhưng muốn tìm kiếm trong mảng để tìm mục có tên "Kristian" để xóa bạn có thể làm điều này:

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

EDIT: Tôi chỉ nhận thấy câu hỏi của bạn được gắn thẻ "jQuery", vì vậy bạn có thể thử $.grep()phương pháp :

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

Tại sao họ thêm quá tải? Chắc chắn bạn có thể vừa đặt! = "Kristian". Mục đích nào quá tải phục vụ?
markthewizard1234

@ markthewizard1234 - Ý của bạn là đối số Boolean "đảo ngược" trong $.grep()? Nó không thêm nhiều trong ví dụ này, trong đó có, tôi có thể đặt !=, nhưng trong các trường hợp khác, bạn có thể đã có một hàm được xác định để thực hiện kiểm tra ngược lại với những gì bạn muốn grep, vì vậy thay vì xác định một chức năng bổ sung bạn chỉ có thể sử dụng quá tải đó để đảo ngược kết quả.
nnnnnn

À, vậy nếu bạn có hàm bao bọc chứa grep, bạn có thể đặt boolean làm tham số. Cảm ơn
markthewizard1234

@ markthewizard1234 - Bạn có thể, nhưng đó không phải là điều tôi nghĩ: hãy tưởng tượng bạn có function isEven(num) { return num%2===0 }. Bạn có thể sử dụng $.grep(someArray, isEven)để chỉ lấy các số chẵn từ mảng hoặc $.grep(someArray, isEven, true)làm ngược lại và nhận các giá trị không chẵn.
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');

Nó sẽ loại bỏ John !


4
Man ... Đến từ java, tôi rất bối rối rằng một việc cơ bản như vậy đòi hỏi phải lọc danh sách ... wtf. Đây là câu trả lời chính xác nhất cho câu hỏi OP tôi đọc cho đến nay.
codepleb

Vâng, đây là một cách tiếp cận tốt. Mặc dù nó cũng sẽ hoạt động trước ES2015 (ES6). Chức năng lọc đã có sẵn kể từ phiên bản 5.1 (2011) ecma
i Intl.org/ecma-262/5.1/#sec-15.4.4.20

40

Bạn có thể sử dụng mảng.filter ().

ví dụ

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

Chức năng mũi tên:

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

Một điều tôi muốn, Sẽ có các nút riêng biệt cho mọi đối tượng trong mảng. nếu tôi muốn xóa đối tượng cụ thể đó trong nút mảng đã nhấp. làm thế nào để làm nó . tôi đã sử dụng js ng-repeat góc để tạo ra các mục. bạn có thể giúp tôi không
Thilak Raj

daCoda nếu bạn có hai điều kiện?
Malcolm Salvador

@MalcolmSalvador nói ví dụ nếu bạn có một điều kiện khác, bạn có thể viết như thế này bên dưới và tiếp tục với các && hoặc || khác nhau điều hành theo nhu cầu của bạn. someArray = someArray.filter (function (returnableObjects) {return returnableObjects.name! == 'Kristian' && cond2Query.age> = 22;});
Biswajit Panday

18

Tôi đã tạo một hàm động lấy các đối tượng Array, Key và value và trả về cùng một mảng sau khi loại bỏ đối tượng mong muốn:

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

        }

Ví dụ đầy đủ: 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"));

15

Đây là một chức năng phù hợp với tôi:

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

Một điều tôi muốn, Sẽ có các nút riêng biệt cho mọi đối tượng trong mảng. nếu tôi muốn xóa đối tượng cụ thể đó trong nút mảng đã nhấp. làm thế nào để làm nó . tôi đã sử dụng js ng-repeat góc để tạo ra các mục. bạn có thể giúp tôi không
Thilak Raj

12

Bạn cũng có thể thử làm một cái gì đó như thế này:

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

11
someArray = jQuery.grep(someArray , function (value) {
        return value.name != 'Kristian';
});

10

Sử dụng hàm splice trên mảng. Chỉ định vị trí của phần tử bắt đầu và độ dài của phần tiếp theo bạn muốn xóa.

someArray.splice(pos, 1);

8

Bình chọn cho UndercoreJS cho công việc đơn giản với mảng.

Hàm _.without () giúp loại bỏ một phần tử:

 _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
    => [2, 3, 4]

Giải pháp tốt nhất. Hoạt động với mảng đối tượng.
Azee

4

Với chức năng mũi tên 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

Giải pháp đơn giản nhất là tạo một bản đồ lưu trữ các chỉ mục cho từng đối tượng theo tên, như sau:

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

Tôi thích ý tưởng này, nhưng cũng phải hỏi, giới hạn sử dụng bộ nhớ cho một ý tưởng như thế này là gì khi các chỉ mục được thêm vào? Tôi có một mảng mà tôi muốn lập chỉ mục trên 2 trường khác nhau trong đối tượng, vì vậy tôi có 2 bản đồ ngoài mảng nguồn ban đầu. Đây có phải là một cái giá nhỏ để trả cho tốc độ tra cứu hay có một giải pháp nào hiệu quả hơn với bộ nhớ?
Brad G.

3

Mặc dù điều này có lẽ không phù hợp với tình huống này nhưng tôi đã phát hiện ra rằng bạn cũng có thể sử dụng deletetừ khóa để xóa một mục khỏi một mảng nếu bạn không cần thay đổi kích thước của mảng, ví dụ

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

Câu trả lời này

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

không làm việc cho nhiều hồ sơ đáp ứng điều kiện. Nếu bạn có hai bản ghi liên tiếp như vậy, chỉ có bản ghi đầu tiên bị xóa và bản còn lại bị bỏ qua. Bạn phải sử dụng:

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

thay thế .


2

Dường như có một lỗi trong cú pháp mảng của bạn, vì vậy giả sử bạn có nghĩa là một mảng trái ngược với một đối tượng, Array.splice là bạn của bạn ở đây:

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

2

Bạn cũng có thể sử dụng chức năng bản đồ .

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
Nhưng nếu bạn muốn lặp qua mảng, sử dụng forEach có tốt hơn không?
corse32

2

Bạn cũng có thể sử dụng 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

Đây là những gì tôi sử dụng.

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

Sau đó, nó đơn giản như nói

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

Thay thế bất kỳ số nào thay cho ba. Sau khi đầu ra dự kiến ​​sẽ là:

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

2

Nếu bạn muốn loại bỏ tất cả các lần xuất hiện của một đối tượng nhất định (dựa trên một số điều kiện) thì hãy sử dụng phương thức mối nối javascript bên trong một vòng lặp.

Vì việc xóa một đối tượng sẽ ảnh hưởng đến độ dài mảng, hãy đảm bảo giảm một bước của bộ đếm, để kiểm tra độ dài vẫn còn nguyên.

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

Đoạn mã trên loại bỏ tất cả các đối tượng có độ tuổi lớn hơn 20.



1

splice (i, 1) trong đó i là chỉ số gia tăng của mảng sẽ loại bỏ đối tượng. Nhưng hãy nhớ mối nối cũng sẽ đặt lại độ dài mảng, vì vậy hãy coi chừng 'không xác định'. Sử dụng ví dụ của bạn, nếu bạn xóa 'Kristian', thì trong lần thực hiện tiếp theo trong vòng lặp, tôi sẽ là 2 nhưng someArray sẽ có độ dài bằng 1, do đó nếu bạn cố xóa "John", bạn sẽ gặp lỗi "không xác định" . Một giải pháp cho điều này mặc dù không thanh lịch là có bộ đếm riêng để theo dõi chỉ số của phần tử cần loại bỏ.


1

Chỉ trả về các đối tượng từ mảng có thuộc tính namekhông phải là "Kristian"

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


Bản giới thiệu:

 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

Khái niệm này sử dụng Lưới Kendo

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

Tôi đoán các câu trả lời rất phân nhánh và thắt nút.

Bạn có thể sử dụng đường dẫn sau để loại bỏ một đối tượng mảng phù hợp với đối tượng được đưa ra trong thuật ngữ JavaScript hiện đại.


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

Nếu bạn muốn truy cập và xóa đối tượng của một mảng đơn giản, bạn có thể thử một cái gì đó như thế này.

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

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.