Dizideki tüm nesnelerin özelliğini kaldır


111

Dizideki badher nesneden özelliği kaldırmak istiyorum . Bir fordöngü kullanmaktan ve onu her nesneden silmekten daha iyi bir yol var mı ?

var array = [{"bad": "something", "good":"something"},{"bad":"something", "good":"something"},...];

for (var i = 0, len = array.length; i < len; i++) {
  delete array[i].bad;
}

Sadece kullanmanın bir yolu prototypeya da başka bir şey olmalı gibi görünüyor . Bilmiyorum. Fikirler?


1
Önemli değil, diğer yollar doğrusal O (n) 'den daha az olamaz. Ne kullanırsanız kullanın, tüm dizi öğelerinize erişmeniz gerekecek
Brian

Prototip? Bu nasıl yardımcı olur? Yoksa tüm bu nesneler aynı kurucunun örnekleri badmi ve ortak bir değeri mi paylaşıyor ?
Bergi

1
@Bergi Prototype JS'ye mi yoksa Arrayörnek teşkil eden prototipe mi atıfta bulunduklarını merak ediyorum
Ian

Döngüden önce array.length'i bir değişkende depolamanız gerektiğinden emin değilim. Eminim profil çıkarırsan acıya değmeyeceğini göreceksin.
Denys Séguret

1
@ZackArgyle Evet, genel durumda daha hızlı bir şey yok.
Denys Séguret

Yanıtlar:


120

Diğer tek yol kozmetiktir ve aslında döngüdür.

Örneğin :

array.forEach(function(v){ delete v.bad });

Notlar:

  • IE8 ile uyumlu olmak istiyorsanız, her biri için bir altlığa ihtiyacınız olacaktır . Prototipten bahsettiğiniz gibi, prototype.js de bir shim'e sahiptir .
  • deleteen kötü "optimizasyon katillerinden" biridir . Bunu kullanmak genellikle uygulamalarınızın performansını bozar. Bir özelliği gerçekten kaldırmak istiyorsanız bundan kaçınamazsınız, ancak genellikle özelliği olarak ayarlayabilir undefinedveya özellik olmadan yeni nesneler oluşturabilirsiniz.

1
Döngünün "sahte" olmasına izin veriliyorsa döngüden çok daha iyi değilfor(var i = 0; i < array.length ) delete array[i].bad
Esailija

1
@Esailija bağlıdır. Kullanmayı seviyorum forEachçünkü kodu daha anlamlı buluyorum (ve uzun zaman önce IE hakkında endişelenmeyi bıraktığım için).
Denys Séguret

1
İkisi de "bu dizideki tüm nesnelerin kötü özelliklerini sil" ifadesini tamamen farklı bir şekilde ifade etmez. forEachbir fordöngü gibi genel ve anlamsal olarak anlamsızdır .
Esailija

1
@Esailija Katılıyorum. Bu yüzden "kozmetik" olduğunu söyledim. Cevabımda net değil mi?
Denys Séguret

Talihsiz. Genellikle forEach'den daha hızlı olan for döngüsüne sadık kalacağım. Ve gerçekten ... IE8 kimin umurunda. Yardım için teşekkürler.
Zack Argyle

174

ES6 ile, her nesneyi, adlandırılmış öznitelikler olmadan yeni bir nesne oluşturmak için parçalarına ayırabilirsiniz:

const newArray = array.map(({dropAttr1, dropAttr2, ...keepAttrs}) => keepAttrs)

16
İlk soruna uygulanıyor olabilirconst newArray = array.map(({ bad, ...item }) => item);
2018 saat

1
Orijinal diziyi (değişmez işlemler) değiştirmediği için bu çok tavsiye edilir
Pizzicato

1
Mevcut olanın üzerine yazmak yerine yeni bir dizi döndürdüğü için bu kabul edilen cevap olmalıdır.
user1275105

harika yanıt, ancak mülk adı nokta (.) içeriyorsa işe yaramıyor, örneğin 'bad.prop'
Yayati

@Amiraslan kullanırdım// eslint-disable-next-line no-unused-vars
piotr_cz

21

Özelliği silmek ve ardından yeni dizi öğesini döndürmek için map kullanmayı tercih ediyorum.

array.map(function(item) { 
    delete item.bad; 
    return item; 
});

12
Bunun orijinal diziyi değiştirdiğinin farkında olun
piotr_cz

1
Bu özel durumda açık returnifade gerekmeyecektir
Sandeep Kumar

4
array.forEach(v => delete v.bad);
Anthony Awuley

14

Eğer kullanırsanız underscore.js :

var strippedRows = _.map(rows, function (row) {
    return _.omit(row, ['bad', 'anotherbad']);
});

9

Prototip kullanan bir çözüm, yalnızca nesneleriniz aynı olduğunda mümkündür:

function Cons(g) { this.good = g; }
Cons.prototype.bad = "something common";
var array = [new Cons("something 1"), new Cons("something 2"), …];

Ama sonra basit (ve O(1)):

delete Cons.prototype.bad;

3

Bence bu en basit varyant

array.map(({good}) => ({good}))

3
soru iyiyi korumak değil, kötüyü kaldırmakla ilgiliydi. Nesnelerinizde tutulacak ve kaldırılacak 10 alan varsa, yukarıdakileri yazmak gerçekten uzun olur.
adrien

1

Bunu, daha okunaklı, anahtar bulunmaması nedeniyle beklenti artışını takip edebilirsiniz:

data.map((datum)=>{
                    return {
                        'id':datum.id,
                        'title':datum.login,
                    }

0

Nesnelerin kopyalanması ve orijinal nesne dizisini etkilememesi için Object.assignbir forEach()döngü içinde kullanmayı önereceğim

var res = [];
array.forEach(function(item) { 
    var tempItem = Object.assign({}, item);
    delete tempItem.bad; 
    res.push(tempItem);
});
console.log(res);

0

Bu soru şimdi biraz eski, ancak kaynak verilerini değiştirmeyen ve minimum manuel çaba gerektiren alternatif bir çözüm sunmak istiyorum:

function mapOut(sourceObject, removeKeys = []) {
  const sourceKeys = Object.keys(sourceObject);
  const returnKeys = sourceKeys.filter(k => !removeKeys.includes(k));
  let returnObject = {};
  returnKeys.forEach(k => {
    returnObject[k] = sourceObject[k];
  });
  return returnObject;
}

const array = [
  {"bad": "something", "good":"something"},
  {"bad":"something", "good":"something"},
];

const newArray = array.map(obj => mapOut(obj, [ "bad", ]));

Hala mükemmelden biraz daha az, ancak bir miktar değişmezliği koruyor ve kaldırmak istediğiniz birden çok özelliği adlandırma esnekliğine sahip. (Önerilere açığız)


0

Vue.js'deki coulmns'u silmeden yeni bir nesneyi craating ile denedim.

let data =this.selectedContactsDto[];

// selectedContactsDto [] = projemde oluşturulan dizi nesnelerinin listesini içeren nesne

console.log (veri); let newDataObj = data.map (({groupsList, customFields, firstname, ... item}) => item); console.log ("newDataObj", newDataObj);


0

Nesne dizisinden bazı anahtar değer çiftlerini kaldırmak için bu örnekte olduğu gibi veritabanı olarak Postgres SQL kullanılır:

Bu, kullanıcı işlevi geri döndür kullanıcı ayrıntıları nesnesidir, satırlardan "api_secret" anahtarını kaldırmamız gerekir:

    function getCurrentUser(req, res, next) { // user function
    var userId = res.locals.userId;
    console.log(userId)
    db.runSQLWithParams("select * from users where id = $1", [userId], function(err, rows) {
      if(err){
        console.log(err)
      }
      var responseObject = {
        _embedded: rows,
      }
      responseObject._embedded[0].api_secret = undefined
      // console.log(api);
      // console.log(responseObject);
      res.json(responseObject);
    }); 
}

Yukarıdaki işlev, nesnenin altına JSON yanıtı olarak geri döner.

 {
    "_embedded": [
        {
            "id": "0123abd-345gfhgjf-dajd4456kkdj",
            "secret_key: "secret",
            "email": "abcd@email.com",
            "created": "2020-08-18T00:13:16.077Z"
        }
    ]
}

Bu satırı ekledikten sonra responseObject._embedded[0].api_secret = undefinedJSON yanıtı olarak aşağıdaki sonucu verir:

{
        "_embedded": [
            {
                "id": "0123abd-345gfhgjf-dajd4456kkdj",
                "email": "abcd@email.com",
                "created": "2020-08-18T00:13:16.077Z"
            }
        ]
    }

0

ES6'daki en kısa yol:

array.forEach(e => {delete e.someKey});

0

Dışarıda çok sayıda kütüphane var. Her şey veri yapınızın ne kadar karmaşık olduğuna bağlıdır (örneğin, derinlemesine iç içe geçmiş anahtarları düşünün)

Derin iç içe geçmiş hiyerarşilerle de çalıştığı için nesne alanlarını seviyoruz (api alanları parametresi için derleme). Dayanarak nesne tarama , bu nedenle hızlı olduğunu biliyorum. İşte basit bir kod örneği

const { Retainer } = require('object-fields');

const array = [
  { bad: 'something', good: 'something' },
  { bad: 'something', good: 'something' }
];

const prune = Retainer(['good']);
prune(array);
console.log(array);
// => [ { good: 'something' }, { good: 'something' } ]

-4

var array = [{"bad": "something", "good":"something"},{"bad":"something", "good":"something"}];
var results = array.map(function(item){
  return {good : item["good"]}
});
console.log(JSON.stringify(results));


Çözümünüzü açıklayabilir misiniz?
sg7

Harita, JavaScript ES6'da yeni bir veri yapısıdır. Ekteki bağlantı size yardımcı olabilir. hackernoon.com/what-you-should-know-about-es6-maps-dc66af6b9a1e
hk_y

Eşyalarınızda çok sayıda sahne varsa bu çözüm iyi değildir.
Koop4

Evet! Farklı bir yaklaşım sağlamaya çalıştım.
hk_y
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.