Nesne özelliğine göre dizi öğesini kaldırma


271

Ben gibi nesnelerin bir dizi var:

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

Belirli bir özelliği özelliğine göre nasıl kaldırabilirim?

Örneğin, field özelliği olarak 'para' ile dizi nesnesini nasıl kaldırabilirim?

Yanıtlar:


382

Bir olasılık:

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

Bunun filteryeni bir dizi oluşturduğunu lütfen unutmayın . Orijinal değişkeni myArrayyeni referansla güncellemenize rağmen, orijinal diziye başvuran diğer değişkenler filtrelenmiş verileri alamaz . Dikkatle kullanın.


6
Not filter()Internet Explorer 9 ve üstü için geçerlidir
jessegavin

@jessegavin gerçekten. İşlevselliği taklit eden çok sayıda iyi es5 şim kütüphanesi olduğunu söylemeliydim (eski tarayıcıları desteklemek istiyorsanız)
jAndy

3
filter()yeni bir dizi oluşturur; bu, değişkeni yeniden atayabiliyorsanız ve ona referans veren başka kod alanları olmadığını biliyorsanız iyi olur. Özellikle orijinal dizi nesnesini değiştirmeniz gerekiyorsa çalışmaz.
Brian Glick

2
Dizi bir ağaç yapısı ar önce iseDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "23 testini değiştirdi"}]}] ve kimliğini silmek istiyorum: 23
unutulmuş

@forgottofly iyi bir nokta - cevap sadece sınırlı durumlarda işe yarar. Sorunuza cevap buldunuz mu?
JackTheKnife

88

Dizi boyunca ve spliceistemediklerinizi yineleyin . Daha kolay kullanım için, dizinin canlı yapısını dikkate almanıza gerek kalmadan geriye doğru yineleyin:

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

3
dizinin canlı doğası ile ne demek istiyorsun? Neit the Dark Absol
sisimh

29
@sisimh, yineleme mantığının bir parçası olarak uzunluğunu kullanarak bir diziyi ileriye doğru yinelerseniz ve öğelerin kaldırıldığı veya eklendiği için uzunluğu değiştiğinde, dizinin sonundan kaçabilir veya işlem yapamazsınız demektir. dizideki her öğe. Geriye gitmek, hareket eden bir uzunluktan ziyade statik bir 0 indeksine doğru çalıştığından daha az olasıdır.
Klors

2
Dizi bir ağaç yapısı ar önce iseDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "23 testini değiştirdi"}]}] ve kimliğini silmek istiyorum: 23
unutulmuş

Açıktır, ancak yalnızca tek bir benzersiz öğeyi kaldırmayı bekliyorsanız, performans için 'if' ifadesine bir mola verebilirsiniz, böylece döngü dizinin geri kalanında gereksiz yere yinelenmez.
Patrick Borkowicz

@Klors Açıkladığınız için teşekkürler. Diziyi yanıttaki gibi her zaman geriye doğru okumak iyi olur mu?
kittu

38

Alan nesnesinden ikinci nesneyi kaldırmak istediğinizi varsayalım.

ES6 ile bu kadar kolay.

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

7
Bunu denedim ama OP dizisinden 3. öğeyi "kaldırmak" yerine, kodunuz "filtrelendi" ve yalnızca 3. öğeyi görüntüledi.
Compaq LE2202x

1
@ CompaqLE2202x 2 yıl sonra muhtemelen sizin için zaten açıktır, ancak gelecekteki geliştiriciler için: spliceorijinal diziyi değiştirir, bu nedenle geri aldığınız değer kaldırılan öğedir, ancak myArrayöğeye bir sonraki baktığınızda eksik olacaktır.
David Mulder

16

Belirli öğenin dizinini almak için lodash'ın findIndex komutunu kullanabilir ve daha sonra onu kullanarak birleştirebilirsiniz.

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

Güncelleme

ES6'nın findIndex () yöntemini de kullanabilirsiniz

FindIndex () yöntemi, dizideki sağlanan test işlevini karşılayan ilk öğenin dizinini döndürür. Aksi takdirde -1 döndürülür.

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

Ağaç yapısı dizisi nedir?
forgottofly

@forgottofly ağaç yapısı? Sanırım myArrayburada bir dizi nesne var.
Sridhar

4
Dizi bir ağaç yapısı ise, daha önce varDeleteOperationArray = [{"id": 3.1, "name": "test 3.1", "activityDetails": [{"id": 22, "name": "test 3.1"}, {"id": 23, "name": "23 testini değiştirdi"}]}] ve kimliği silmek istiyorum: 23
unutulmuş

9

İşte jQuery grep kullanan başka bir seçenek. Geçiş truesenin fonksiyonuna uygun grep kaldırır öğeleri sağlamak için üçüncü parametre olarak.

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

Zaten jQuery kullanıyorsanız, hiçbir şim gerekli değildir, bu da kullanmanın aksine yararlı olabilir Array.filter.


7

ES6'da sadece bir satır.

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

:)


3

JQuery kullanmıyorsanız kod aşağıdadır. gösteri

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

Ayrıca çok sayıda işlevi olan alt çizgi kitaplığı da kullanabilirsiniz.

Alt çizgi , JavaScript için birçok işlevsel programlama desteği sağlayan bir yardımcı program kitaplığıdır


5
Bu, web'de bırakmak için çok tehlikeli bir örnektir ... örnek verilerle çalışır, ancak başka bir şeyle değil. splice (i), değerin para olduğu ilk örnekten başlayarak ve sonra dizideki tüm öğeleri kaldıracağı anlamına gelir; Ekleme (i, 1) olarak değiştirdiysek, bir sonraki sıralı öğeyi değerlendirmeyeceği için hala yanlış olur (i'yi de azaltmanız gerekir) Bu nedenle dizilerdeki kaldırma işlemlerini geriye doğru işlemelisiniz, böylece bir öğe, işlenecek sonraki öğelerin dizinlerini değiştirmiyor
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

Öğe dizideki bir nesnedir. 3. parametre true, fonksiyon mantığınıza başarısız olan falsebir dizi öğeyi döndürür, fonksiyon mantığınızı başarısız olan bir dizi öğeyi döndürür.


3

Lodash kütüphanesini kullanma :

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>


2

Yukarıdaki bazı yorumlara dayanarak, bir anahtar adı ve anahtar değerine dayalı olarak bir nesnenin nasıl kaldırılacağı kodu

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

1

jAndy'nin çözümü muhtemelen en iyisidir, ancak filtreye güvenemezseniz şöyle bir şey yapabilirsiniz:

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
Neden filter () öğesine güvenemiyorum?
imperium2335

2
IE8 ve altındaki veya eski tarayıcılar tarafından desteklenmeyen JavaScript 1.6'nın bir parçası olduğu için.
Rob

-1

Lodash kütüphanesini kullanmak bu kadar basit

_.remove(myArray , { field: 'money' });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.