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?


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.

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)

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

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

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;

5

Moim zdaniem to najprostszy wariant

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

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,
                    }

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

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)


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


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": "abcd@email.com",
            "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": "abcd@email.com",
                "created": "2020-08-18T00:13:16.077Z"
            }
        ]
    }

0

Najkrótsza droga w ES6:

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

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/object-fields@2.0.19"></script>

Zastrzeżenie : jestem autorem pól obiektowych


0

ES6:

const newArray = array.map(({keepAttr1, keepAttr2}) => ({keepAttr1, newPropName: keepAttr2}))

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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.