Bir nesneden birden çok anahtar/değer çiftini dinamik olarak kaldırma

Diyelim ki bir dizi nesnem var. İstemediğim bazı anahtarlar/değerler var. Bir anahtar/değer çiftini silmenin geleneksel yolu şu şekilde delete kullanmaktır:

for (var i = 0; i < tracks.length; i++) {
  delete tracks[i]["currency"];
  ...
}

The objects I'm pulling in could have over 30 pairs. Is there a way where I can state which pairs I want and remove all others? So for example in this array of objects I only want to keep trackName, kind, price

var tracks = [{
    trackNumber: "01",
    trackName: "Track 1",
    trackDuration: "5:35",
    kind: "song",
    currency: "USD",
    price: 1.29
}, {
    trackNumber: "02",
    trackName: "Track 2",
    trackDuration: "5:15",
    kind: "song",
    currency: "USD",
    price: 1.29
}, {
    trackNumber: "03",
    trackName: "Track 3",
    trackDuration: "5:07",
    kind: "song",
    currency: "USD",
    price: 1.29
}, {
    trackNumber: "04",
    trackName: "Track 4",
    trackDuration: "0:16",
    kind: "song",
    currency: "USD",
    price: 1.29
}, {
    trackNumber: "05",
    trackName: "Track 5",
    trackDuration: "5:35",
    kind: "song",
    currency: "USD",
    price: 1.29
}];
3
sizin için yapmak için bir işlev yapmanız gerekecek, bu da (bağlı olarak) yeni bir nesne döndürecektir
katma yazar Fallenreaper, kaynak
neden dizi üzerinde yinelenen .map() 'yi kullanmıyorsunuz? İstediğiniz değerleri nesne olarak döndürün ve değişken parçaları değiştirin
katma yazar Dhiraj, kaynak
Neden sadece döngü ve silmek değil?
katma yazar thefourtheye, kaynak

6 cevap

Dizinin üzerine girin ve her Nesneden ne istediğinizi saklayın.

var keep = ['trackName', 'kind', 'price'];

for(var i = 0;i < tracks.length; i++){

    for(var key in tracks[i]){
        if(keep.indexOf(key) === -1)delete tracks[i][key];
    }

}
4
katma
İkinci for loop koşulunda, tam olarak ne değerlendiriyor? Dizinin indeks sayısının -1'e eşit olması kafamı karıştırdı.
katma yazar Carl Edwards, kaynak
bir dizi yerine bir arama tablosu kullanarak yürütmek mekanik olarak daha hızlı olacaktır, keep = {trackName: 1, kind: 1, price: 1}; ve sonra basit 'ı kullanabilirsiniz. if (keep [key]) { indexOf() yerine
katma yazar dandavis, kaynak
js, dizide bulunmayan tüm öğelerin dizini olarak -1 değerini kullanır.
katma yazar dandavis, kaynak
@WashingtonGuedes: hayır, delete tehlikelidir, çünkü bu dizini kaldırmaz ...
katma yazar dandavis, kaynak
@CarlEdwards indexOf`, anahtar keep konumunda bulunmazsa -1 değerini döndürür.
katma yazar Omar Elawady, kaynak
delete, özelliği dizini ile kaldırır. ve istediği bu. Neden tehlikeli?
katma yazar Omar Elawady, kaynak
@CarlEdwards indexOf . daha fazla bilgi için buna bakın.
katma yazar Omar Elawady, kaynak
Haklısın .. diziler için tehlikelidir .. nesneler için sorun değil
katma yazar user4227915, kaynak

İstediğinin bu olup olmadığından emin değilim, ancak listenin içinde dönecek ve içinde sadece verilen tuşlarla aynı listeye dönecektir. tuşları bir anahtar dizisidir.

function LimitArray(keys, list){
    var returnArr = [];
    for (var i in list){
       var row = {};
       for (key in list[i]){
          row[key] = list[i][key];
       }
       returnArr.push(row);
    }
    return returArr;
}

Bunu orijinal listeyi değiştirmek için birkaç yolla da yazabilirsiniz, ancak bunun özellikle istediğinizden emin değilim, bu yüzden yeni bir liste döndürdüm.

Orijinali değiştirmek istiyorsanız, şöyle bir şey yapabilirsiniz:

var select = ["a","b"]
list.map(function(val,index, array)
   {
   var keys = Object.keys(val);
   for (var key in keys){
      if(-1 == select.indexOf(keys[key]])  delete val[keys[key]];
   }}.bind(this));

Bunun gerekli olanı da yapması gerektiğine inanıyorum. Listede dolaşacak ve seçimde bulunmayan tüm tuşları kaldıracaktır.

1
katma

Bu daha zarif olduğunu düşündüğüm için önereceğim şey:

// create new array of objects from old one
var fixed = jQuery.map(tracks, function(element, index){
    return {"trackName": element.trackName, "kind": element.kind, "price": element.price};
}); 
// delete old array   
tracks = null;
1
katma

Kendinden açıklamalı bir çözüm:

// what you want to keep:
var want_to_keep = ['trackName', 'kind', 'price'];

// loop trough every main element of tracks:
for (var i=0; i<tracks.length; i++)
   //now go trough every element of the current track:
    for (var key in tracks[i])
       //check if the current track key is wanted:
        if (want_to_keep.indexOf(key) < 0)
            delete tracks[i][el];
0
katma

Alt çizgi " .pick (object, * keys)", " .omit (object, * keys)" altını kullanır ve yeni nesneleri yeni bir diziye iter.

0
katma

Gelebildiğim en basit çözüm:

<div class="snippet" data-lang="js" data-hide="true"> <div class="snippet-code snippet-currently-hidden">

/**
 * Returns new collection which items contains only specified properties
 * @param {Array} collection of items
 * @param {Array} properties to keep
 */

function keepCollectionProperties(collection, properties) {
    return collection.map(function(item) {
        var newItem = {}
        for(var i = 0, prop; prop = properties[i]; i++)
            if (typeof item[prop] !== 'undefined')
                newItem[prop] = item[prop]
        return newItem
    })
}

var tracks = [{
    trackNumber: "01",
    trackName: "Track 1",
    trackDuration: "5:35",
    kind: "song",
    currency: "USD",
    price: 1.29
}, {
    trackNumber: "02",
    trackName: "Track 2",
    trackDuration: "5:15",
    kind: "song",
    currency: "USD",
    price: 1.29
}, {
    trackNumber: "03",
    trackName: "Track 3",
    trackDuration: "5:07",
    kind: "song",
    currency: "USD",
    price: 1.29
}, {
    trackNumber: "04",
    trackName: "Track 4",
    trackDuration: "0:16",
    kind: "song",
    currency: "USD",
    price: 1.29
}, {
    trackNumber: "05",
    trackName: "Track 5",
    trackDuration: "5:35",
    kind: "song",
    currency: "USD",
    price: 1.29
}];

var output = keepCollectionProperties(tracks, ['trackName', 'kind', 'price'])
document.write(JSON.stringify(output))
</div> </div>

Note: avoid using of delete, it changes "shape" of object and harms performance. Use item.prop = null where possible. My function returns new collection, so it is not necessary, but if you plan to populate the new collection again, it would be better to set unwanted props to null.

0
katma