Rimuovi proprietà per tutti gli oggetti nell'array


110

Voglio rimuovere la badproprietà da ogni oggetto nell'array. C'è un modo migliore per farlo che usare un forciclo ed eliminarlo da ogni oggetto?

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

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

Sembra che dovrebbe esserci un modo per usarlo prototype, o qualcosa del genere. Non lo so. Idee?


1
Non importa, gli altri modi non possono essere meno lineari di O (n). Qualunque cosa tu usi, richiederà l'accesso a tutti gli elementi dell'array
Brian

Prototipo? Come potrebbe aiutare? O tutti quegli oggetti sono istanze dello stesso costruttore e condividono un valore comune per bad?
Bergi

1
@Bergi, mi chiedo se si riferissero a prototypeJS, o al Arrayprototipo, esemplificato da dystroy
Ian

Non sono sicuro che dovresti memorizzare array.length in una variabile prima del ciclo. Sono sicuro che vedrai che non vale la pena se fai il profilo.
Denys Séguret

1
@ZackArgyle Sì, nel caso generale non c'è niente di più veloce.
Denys Séguret

Risposte:


120

Gli unici altri modi sono cosmetici e sono in realtà dei loop.

Per esempio :

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

Appunti:

  • se vuoi essere compatibile con IE8, avresti bisogno di uno spessore per forEach . Mentre parli di prototype, prototype.js ha anche uno shim .
  • deleteè uno dei peggiori "killer dell'ottimizzazione" . Usarlo spesso interrompe le prestazioni delle tue applicazioni. Non puoi evitarlo se vuoi davvero rimuovere una proprietà, ma spesso puoi impostare la proprietà undefinedo semplicemente creare nuovi oggetti senza la proprietà.

1
Non molto meglio del loop se il loop può essere "falso" - anche uno allineato: Pfor(var i = 0; i < array.length ) delete array[i].bad
Esailija

1
@Esailija Depends. Mi piace usare forEachperché trovo il codice più espressivo (e perché ho smesso di preoccuparmi di IE molto tempo fa).
Denys Séguret

1
Nessuno dei due esprime "cancella proprietà cattiva di tutti gli oggetti in questo array" in modo radicalmente diverso. forEachè generico e semanticamente privo di significato di per sé, come un forciclo.
Esailija

1
@Esailija sono d'accordo. Ecco perché ho precisato che era "cosmetico". Non è chiaro nella mia risposta?
Denys Séguret

Sfortunato. Continuerò con il ciclo for che è generalmente più veloce di forEach. E davvero ... chi se ne frega di IE8. Grazie per l'aiuto.
Zack Argyle

173

Con ES6, puoi decostruire ogni oggetto per crearne uno nuovo senza attributi denominati:

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

16
Applicando al problema iniziale potrebbe essereconst newArray = array.map(({ bad, ...item }) => item);
dhilt

1
Questo è molto consigliato poiché non modifica l'array originale (operazioni immutabili)
Pizzicato

1
Questa dovrebbe essere la risposta accettata perché restituisce un nuovo array, invece di sovrascrivere quello esistente.
user1275105

ottima risposta ma non funziona se il nome della proprietà contiene un punto (.) Ad esempio "bad.prop"
Yayati

@Amiraslan // eslint-disable-next-line no-unused-vars
userei

20

Preferisco usare map per eliminare la proprietà e quindi restituire il nuovo elemento dell'array.

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

12
Tieni presente che questo muta l'array originale
piotr_cz

1
In questo caso particolare returnnon sarebbe richiesta una dichiarazione esplicita
Sandeep Kumar

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

14

Se utilizzi underscore.js :

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

9

Una soluzione che utilizza prototipi è possibile solo quando i tuoi oggetti sono simili:

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

Ma poi è semplice (e O(1)):

delete Cons.prototype.bad;

3

Secondo me questa è la variante più semplice

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

3
la domanda era rimuovere il male, non mantenere il buono. Se i tuoi oggetti hanno 10 campi da mantenere e uno da rimuovere, quanto sopra diventa molto lungo da digitare.
adrien

1

Puoi seguire questo, più leggibile, senza aumento delle aspettative a causa della chiave non trovata:

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

0

Suggerirò di utilizzare Object.assignall'interno di un forEach()ciclo in modo che gli oggetti vengano copiati e non influisca sulla matrice originale di oggetti

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

0

Questa domanda è un po 'vecchia ora, ma vorrei offrire una soluzione alternativa che non muta i dati di origine e richiede uno sforzo manuale minimo:

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", ]));

È ancora un po 'meno che perfetto, ma mantiene un certo livello di immutabilità e ha la flessibilità di nominare più proprietà che si desidera rimuovere. (Suggerimenti benvenuti)


0

Ho provato a craking un nuovo oggetto senza eliminare i coulmns in Vue.js.

let data =this.selectedContactsDto[];

// selectedContactsDto [] = oggetto con elenco di oggetti array creati nel mio progetto

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


0

Per rimuovere alcune coppie di valori chiave dall'array di oggetti, utilizza Postgres SQL come database come questo esempio:

Questa è la funzione utente restituisce l'oggetto dettagli utente, dobbiamo rimuovere la chiave "api_secret" dalle righe:

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

La funzione precedente restituisce l'oggetto sotto come risposta JSON prima

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

Dopo aver aggiunto questa riga, responseObject._embedded[0].api_secret = undefinedviene fornito il risultato seguente come risposta JSON:

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

0

La via più breve in ES6:

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

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


Potresti spiegare la tua soluzione?
sg7

Map è una nuova struttura dati in JavaScript ES6. Il link allegato potrebbe aiutarti. hackernoon.com/what-you-should-know-about-es6-maps-dc66af6b9a1e
hk_y

questa soluzione non è buona se hai molti oggetti di scena nei tuoi oggetti.
Koop4

Sì! Ho cercato di fornire un approccio diverso.
hk_y
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.