Usuń właściwość dla wszystkich obiektów w tablicy

117

Chcę usunąć badwłaściwość z każdego obiektu w tablicy. Czy jest na to lepszy sposób niż użycie forpętli i usunięcie jej z każdego obiektu?

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

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

Wygląda na to, że powinien być sposób użycia prototype, czy coś. Nie wiem Pomysły?

Zack Argyle
źródło
1
Nie ma znaczenia, inne sposoby nie mogą uzyskać mniej niż liniowe O (n). Cokolwiek użyjesz, będzie wymagało dostępu do wszystkich elementów twojej tablicy
Brian
Prototyp? Jak by to pomogło? A może wszystkie te obiekty są instancjami tego samego konstruktora i mają wspólną wartość dla bad?
Bergi
1
@Bergi Zastanawiam się, czy odnosili się do prototypeJS, czy Arrayprototypu, którego przykładem dystroy jest
Ian
Nie jestem pewien, czy przed zapętleniem należy przechowywać array.length w zmiennej. Jestem pewien, że przekonasz się, że profilowanie nie jest warte bólu.
Denys Séguret
1
@ZackArgyle Tak, w ogólnym przypadku nie ma nic szybszego.
Denys Séguret

Odpowiedzi:

125

Jedyne inne sposoby są kosmetyczne i są faktycznie pętlami.

Na przykład :

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

Uwagi:

  • jeśli chcesz być kompatybilny z IE8, potrzebujesz podkładki forEach . Jak wspomniałeś o prototypie, prototype.js również ma podkładkę .
  • deletejest jednym z najgorszych „zabójców optymalizacji” . Używanie go często obniża wydajność aplikacji. Nie możesz tego uniknąć, jeśli naprawdę chcesz usunąć właściwość, ale często możesz ustawić właściwość na undefinedlub po prostu zbudować nowe obiekty bez właściwości.
Denys Séguret
źródło
1
Niewiele lepsze niż pętla, jeśli pętla może być „fałszywa” - również for(var i = 0; i < array.length ) delete array[i].bad
jedna w linii
1
@Esailija Depends. Lubię używać, forEachponieważ uważam, że kod jest bardziej wyrazisty (i ponieważ już dawno przestałem się martwić o IE).
Denys Séguret
1
Żaden z nich nie wyraża radykalnie inaczej „usuń złą właściwość wszystkich obiektów w tej tablicy”. forEachjest sam w sobie generyczny i semantycznie bez znaczenia, jak forpętla.
Esailija
1
@Esailija Zgadzam się. Dlatego sprecyzowałam, że to „kosmetyk”. Czy nie jest to jasne w mojej odpowiedzi?
Denys Séguret
Niefortunny. Będę trzymał się pętli for, która jest generalnie szybsza niż forEach. I naprawdę ... kogo obchodzi IE8. Dzięki za pomoc.
Zack Argyle
185

W ES6 możesz zdekonstruować każdy obiekt, aby utworzyć nowy bez nazwanych atrybutów:

const newArray = array.map(({dropAttr1, dropAttr2, ...keepAttrs}) => keepAttrs)
piotr_cz
źródło
17
Jeśli chodzi o początkowy problem, może to byćconst newArray = array.map(({ bad, ...item }) => item);
dhilt
1
Jest to bardzo zalecane, ponieważ nie modyfikuje oryginalnej tablicy (niezmienne operacje)
Pizzicato
1
Powinna to być akceptowana odpowiedź, ponieważ zwraca nową tablicę zamiast nadpisywać istniejącą.
user1275105
świetna odpowiedź, ale nie działa, jeśli nazwa właściwości zawiera kropkę (.), np. „bad.prop”
Yayati
@Amiraslan, którego // eslint-disable-next-line no-unused-vars
użyłbym
21

Wolę używać map, aby usunąć właściwość, a następnie zwrócić nowy element tablicy.

array.map(function(item) { 
    delete item.bad; 
    return item; 
});
ex0b1t
źródło
13
Należy pamiętać, że
zmienia
1
W tym konkretnym przypadku wyraźne returnoświadczenie nie byłoby wymagane
Sandeep Kumar
4
array.forEach(v => delete v.bad);
Anthony Awuley
14

Jeśli używasz underscore.js :

var strippedRows = _.map(rows, function (row) {
    return _.omit(row, ['bad', 'anotherbad']);
});
Cody
źródło
9

Rozwiązanie wykorzystujące prototypy jest możliwe tylko wtedy, gdy Twoje obiekty są podobne:

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

Ale potem jest to proste (i O(1)):

delete Cons.prototype.bad;
Bergi
źródło
5

Moim zdaniem to najprostszy wariant

array.map(({good}) => ({good}))
maplemap
źródło
3
pytanie dotyczyło usuwania tego, co złe, a nie zachowania tego, co dobre. Jeśli twoje obiekty mają 10 pól do zachowania i jedno do usunięcia, powyższe zajmuje naprawdę dużo czasu.
adrien
1

Możesz śledzić to, bardziej czytelne, a nie oczekiwane zwiększenie z powodu nieznalezionego klucza:

data.map((datum)=>{
                    return {
                        'id':datum.id,
                        'title':datum.login,
                    }
Maifee Ul Asad
źródło
0

Zasugeruję użycie Object.assignw forEach()pętli, aby obiekty były kopiowane i nie wpływały na oryginalną tablicę obiektów

var res = [];
array.forEach(function(item) { 
    var tempItem = Object.assign({}, item);
    delete tempItem.bad; 
    res.push(tempItem);
});
console.log(res);
Ankit Agarwal
źródło
0

To pytanie jest teraz trochę stare, ale chciałbym zaoferować alternatywne rozwiązanie, które nie powoduje mutacji danych źródłowych i wymaga minimalnego wysiłku ręcznego:

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

Nadal jest trochę mniej niż doskonały, ale zachowuje pewien poziom niezmienności i ma elastyczność umożliwiającą nazwanie wielu właściwości, które chcesz usunąć. (Mile widziane sugestie)

James Marks
źródło
0

próbowałem z craetingiem nowego obiektu bez usuwania coulmns w Vue.js.

let data =this.selectedContactsDto[];

// selectedContactsDto [] = obiekt z listą obiektów tablicy utworzonych w moim projekcie

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

Sunali Bandara
źródło
0

Aby usunąć parę klucz-wartość z tablicy obiektów, użyj Postgres SQL jako bazy danych, jak w tym przykładzie:

To jest obiekt szczegółów użytkownika zwracający funkcję użytkownika, musimy usunąć klucz "api_secret" z wierszy:

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

Powyższa funkcja zwraca poniżej obiekt jako odpowiedź JSON wcześniej

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

Po dodaniu tej linii responseObject._embedded[0].api_secret = undefineddaje poniższy wynik jako odpowiedź JSON:

{
        "_embedded": [
            {
                "id": "0123abd-345gfhgjf-dajd4456kkdj",
                "email": "[email protected]",
                "created": "2020-08-18T00:13:16.077Z"
            }
        ]
    }
akshay_sushir
źródło
0

Najkrótsza droga w ES6:

array.forEach(e => {delete e.someKey});
Idan
źródło
0

Istnieje wiele bibliotek. Wszystko zależy od tego, jak skomplikowana jest struktura danych (np. Rozważ głęboko zagnieżdżone klucze)

Lubimy pola obiektowe, ponieważ działa również z głęboko zagnieżdżonymi hierarchiami (parametr budowania dla pól API). Oto prosty przykład kodu

// const objectFields = require('object-fields');

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

const retain = objectFields.Retainer(['good']);
retain(array);
console.log(array);
// => [ { good: 'something' }, { good: 'something' } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Zastrzeżenie : jestem autorem pól obiektowych

Vincent
źródło
0

ES6:

const newArray = array.map(({keepAttr1, keepAttr2}) => ({keepAttr1, newPropName: keepAttr2}))
Kanan Farzali
źródło
-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));

hk_y
źródło
Czy mógłbyś wyjaśnić swoje rozwiązanie?
sg7
Mapa to nowa struktura danych w JavaScript ES6. Załączony link może ci pomóc. hackernoon.com/what-you-should-know-about-es6-maps-dc66af6b9a1e
hk_y
to rozwiązanie nie jest dobre, jeśli masz wiele rekwizytów w swoich przedmiotach.
Koop4
Tak! Próbowałem przedstawić inne podejście.
hk_y