Xóa phần tử mảng dựa trên thuộc tính đối tượng


271

Tôi có một loạt các đối tượng như vậy:

var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];

Làm thế nào để tôi loại bỏ một cái cụ thể dựa trên tài sản của nó?

ví dụ: Làm thế nào tôi có thể loại bỏ đối tượng mảng bằng 'tiền' làm thuộc tính trường?

Câu trả lời:


383

Một khả năng:

myArray = myArray.filter(function( obj ) {
    return obj.field !== 'money';
});

Xin lưu ý rằng filtertạo ra một mảng mới. Bất kỳ biến nào khác đề cập đến mảng ban đầu sẽ không nhận được dữ liệu được lọc mặc dù bạn cập nhật biến ban đầu của mình myArrayvới tham chiếu mới. Sử dụng cẩn thận.


6
Lưu ý rằng filter()chỉ có sẵn cho Internet Explorer 9+
jessegavin

@jliegavin thực sự. Tôi nên đã đề cập rằng có rất nhiều thư viện shim es5 tốt có sẵn, bắt chước chức năng (chỉ trong trường hợp bạn muốn hỗ trợ các trình duyệt cũ)
jAndy

3
filter()tạo một mảng mới, sẽ ổn nếu bạn có thể gán lại biến và biết rằng không có các vùng mã khác có tham chiếu đến nó. Điều này sẽ không hoạt động nếu bạn đặc biệt cần sửa đổi đối tượng mảng ban đầu.
Brian Glick

2
Điều gì xảy ra nếu mảng là cấu trúc cây ar trướcDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "ActivityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "đã thay đổi bài kiểm tra 23"}]}] và tôi muốn xóa id: 23
tha thứ vào

@forgottofly điểm tốt - câu trả lời chỉ hoạt động cho các trường hợp hạn chế. Bạn đã tìm thấy câu trả lời cho câu hỏi của bạn?
JackTheKnife

88

Lặp lại qua mảng và splicera những cái bạn không muốn. Để sử dụng dễ dàng hơn, lặp lại ngược lại để bạn không phải tính đến bản chất sống của mảng:

for (var i = myArray.length - 1; i >= 0; --i) {
    if (myArray[i].field == "money") {
        myArray.splice(i,1);
    }
}

3
bạn có ý nghĩa gì bởi bản chất sống của mảng? @Neit the Dark
Tuyệt đối

29
@sisimh có nghĩa là nếu bạn lặp đi lặp lại qua một mảng bằng cách sử dụng độ dài của nó như là một phần của logic lặp và độ dài của nó thay đổi bởi vì nó có các phần tử bị loại bỏ hoặc thêm vào, bạn có thể sẽ chạy hết phần cuối của mảng hoặc không thực hiện thao tác cho mỗi mục trong mảng. Đi lùi làm cho điều đó ít có khả năng hơn vì nó hoạt động theo chỉ số 0 tĩnh thay vì chiều dài di chuyển.
Klors 10/07/2015

2
Điều gì xảy ra nếu mảng là cấu trúc cây ar trướcDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "ActivityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "đã thay đổi bài kiểm tra 23"}]}] và tôi muốn xóa id: 23
tha thứ vào

Rõ ràng nhưng nếu bạn chỉ muốn loại bỏ một yếu tố duy nhất, bạn có thể sử dụng câu lệnh 'if' để thực hiện để vòng lặp không cần lặp lại trên phần còn lại của mảng.
Patrick Borkowicz

@Klors Cảm ơn bạn đã giải thích. Có tốt không khi luôn đọc các mảng ngược như trong câu trả lời?
kittu

38

Giả sử bạn muốn xóa đối tượng thứ hai bởi thuộc tính trường.

Với ES6, điều này thật dễ dàng.

myArray.splice(myArray.findIndex(item => item.field === "cStatus"), 1)

7
Tôi đã thử điều này nhưng thay vì "xóa" mục thứ 3 khỏi mảng của OP, mã của bạn "được lọc" và chỉ hiển thị mục thứ 3.
Compaq LE2202x

1
@ CompaqLE2202x 2 năm sau đó có thể là điều hiển nhiên đối với bạn, nhưng đối với các nhà phát triển trong tương lai: splicethay đổi mảng ban đầu, do đó, giá trị bạn nhận được là mục đã bị xóa, nhưng nếu bạn nhìn vào myArraymục tiếp theo sẽ bị thiếu.
David Mulder

17

Bạn có thể sử dụng find Index của lodash để lấy chỉ mục của phần tử cụ thể và sau đó ghép bằng cách sử dụng nó.

myArray.splice(_.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

Cập nhật

Bạn cũng có thể sử dụng find Index () của ES6

Phương thức find Index () trả về chỉ mục của phần tử đầu tiên trong mảng thỏa mãn hàm kiểm tra được cung cấp. Nếu không -1 được trả về.

myArray.splice(myArray.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

Mảng là một cấu trúc cây là gì?
tha thứ vào

@forgottofly cấu trúc cây? Tôi nghĩ rằng myArrayđây là một loạt các đối tượng.
Sridhar

4
Điều gì xảy ra nếu mảng là cấu trúc cây var beforeDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "ActivityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "đã thay đổi bài kiểm tra 23"}]}] và tôi muốn xóa id: 23
tha thứ vào

9

Đây là một tùy chọn khác sử dụng jQuery grep. Vượt qua truenhư tham số thứ ba để đảm bảo grep loại bỏ các mục phù hợp với chức năng của bạn.

users = $.grep(users, function(el, idx) {return el.field == "money"}, true)

Nếu bạn đã sử dụng jQuery thì không cần sử dụng shim, điều này có thể hữu ích thay vì sử dụng Array.filter.


8

Trong ES6, chỉ một dòng.

const arr = arr.filter(item => item.key !== "some value");

:)


3

Sau đây là mã nếu bạn không sử dụng jQuery. Bản giới thiệu

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];

alert(myArray.length);

for(var i=0 ; i<myArray.length; i++)
{
    if(myArray[i].value=='money')
        myArray.splice(i);
}

alert(myArray.length);

Bạn cũng có thể sử dụng thư viện gạch dưới có nhiều chức năng.

Underscore là một thư viện vành đai tiện ích cho JavaScript cung cấp rất nhiều hỗ trợ lập trình chức năng


5
Đây là một ví dụ rất nguy hiểm để lại trên web ... nó hoạt động với dữ liệu ví dụ, nhưng không phải với bất cứ điều gì khác. splice (i) có nghĩa là nó sẽ loại bỏ tất cả các phần tử trong mảng bắt đầu tại và sau phiên bản đầu tiên trong đó giá trị là tiền, điều này không thỏa mãn yêu cầu từ op. Nếu chúng tôi thay đổi thành splice (i, 1) thì nó vẫn không chính xác vì nó sẽ không đánh giá mục tiếp theo tiếp theo (bạn cũng sẽ phải giảm i) Đây là lý do tại sao bạn nên xử lý loại bỏ các hoạt động trong mảng ngược, để loại bỏ một mục không thay đổi chỉ mục của các mục tiếp theo cần xử lý
Chris Schaller

3
var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];
console.log(myArray.length); //3
myArray = $.grep(myArray, function(element, index){return element.field == "money"}, true);
console.log(myArray.length); //2

Phần tử là một đối tượng trong mảng. Tham số thứ 3 truecó nghĩa là sẽ trả về một mảng các phần tử làm hỏng logic chức năng của bạn, falsecó nghĩa là sẽ trả về một mảng các phần tử làm hỏng logic chức năng của bạn.


3

Dựa trên một số ý kiến ​​dưới đây là mã làm thế nào để loại bỏ một đối tượng dựa trên tên khóa và giá trị khóa

 var items = [ 
  { "id": 3.1, "name": "test 3.1"}, 
  { "id": 22, "name": "test 3.1" }, 
  { "id": 23, "name": "changed test 23" } 
  ]

    function removeByKey(array, params){
      array.some(function(item, index) {
        return (array[index][params.key] === params.value) ? !!(array.splice(index, 1)) : false;
      });
      return array;
    }

    var removed = removeByKey(items, {
      key: 'id',
      value: 23
    });

    console.log(removed);

3

Sử dụng thư viện lodash :

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];
var newArray = _.remove(myArray, function(n) {
  return n.value === 'money';;
});
console.log('Array');
console.log(myArray);
console.log('New Array');
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>


1

Giải pháp của jAndy có lẽ là tốt nhất, nhưng nếu bạn không thể dựa vào bộ lọc, bạn có thể làm một cái gì đó như:

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: "money"}
];

myArray.remove_key = function(key){
    var i = 0, 
        keyval = null;
    for( ; i < this.length; i++){
        if(this[i].field == key){
            keyval = this.splice(i, 1);
            break;
        }
    }
    return keyval;
}

1
Tại sao tôi không thể dựa vào bộ lọc ()?
đế chế2335

2
Bởi vì nó là một phần của JavaScript 1.6, không được IE8 hỗ trợ và các trình duyệt cũ hơn hoặc cũ hơn.
Rob M.

-1

Sử dụng thư viện lodash nó đơn giản như thế này

_.remove(myArray , { field: 'money' });
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.