Видалити властивість для всіх об’єктів у масиві


111

Я хочу видалити badвластивість з кожного об'єкта в масиві. Чи є кращий спосіб це зробити, ніж використовувати forцикл і видалити його з кожного об’єкта?

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

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

Просто здається, що повинен бути спосіб використовувати prototypeчи щось інше. Не знаю. Ідеї?


1
Немає значення, інші способи не можуть отримати менше, ніж лінійний O (n). Що б ви не використовували, вам знадобиться доступ до всіх ваших елементів масиву
Брайан

Прототип? Як би це допомогло? Або всі ці об’єкти є екземплярами одного конструктора і мають спільне значення для bad?
Бергі

1
@Bergi Цікаво, мали на увазі вони, маючи на увазі прототипJS, або Arrayпрототип, прикладом якого був дистрой
Ян

Я не впевнений, що слід зберігати array.length у змінній перед циклічним циклом. Я впевнений, ви побачите, що це не вагомо, якщо ви профілюєте.
Denys Séguret

1
@ZackArgyle Так, у загальному випадку немає нічого швидшого.
Denys Séguret

Відповіді:


120

Єдині інші способи - це косметичні, і насправді це петлі.

Наприклад :

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

Примітки:

  • якщо ви хочете бути сумісним з IE8, вам знадобиться підкладка для forEach . Як ви вже згадували prototype, prototype.js також має простий варіант .
  • deleteє одним з найгірших "вбивць оптимізації" . Його використання часто порушує ефективність ваших додатків. Ви не можете уникнути цього, якщо хочете дійсно видалити властивість, але часто ви можете або встановити для нього властивість, undefinedабо просто побудувати нові об’єкти без властивості.

1
Не набагато краще, ніж шлейф, якщо шлейфу дозволено бути "фальшивим" - теж викладений: Pfor(var i = 0; i < array.length ) delete array[i].bad
Esailija

1
@Esailija Залежить. Мені подобається використовувати, forEachтому що я вважаю код більш виразним (і тому, що я перестав турбуватися про IE давно).
Denys Séguret

1
Жоден з них не виражає "видалити погані властивості всіх об'єктів у цьому масиві" кардинально по-різному. forEachє загальним і семантично безглуздим сам по собі, як forцикл.
Esailija

1
@Esailija Я згоден. Ось чому я визначив, що це "косметично". Хіба це не зрозуміло у моїй відповіді?
Denys Séguret

Нещасна. Я дотримуюся циклу for, який, як правило, швидший, ніж forEach. І справді ... хто дбає про IE8. Дякую за допомогу.
Zack Argyle

174

За допомогою ES6 ви можете деконструювати кожен об'єкт, щоб створити новий без іменованих атрибутів:

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

16
Якщо звернутися до початкової проблеми, це може бутиconst newArray = array.map(({ bad, ...item }) => item);
dhilt

1
Це дуже рекомендується, оскільки воно не змінює початковий масив (незмінні операції)
Pizzicato

1
Це має бути прийнятою відповіддю, оскільки вона повертає новий масив, замість того, щоб перезаписати існуючий.
користувач1275105

чудова відповідь, але не працює, якщо назва власності містить крапку (.), напр. 'bad.prop'
Yayati

@Amiraslan я б використав// eslint-disable-next-line no-unused-vars
piotr_cz

21

Я вважаю за краще використовувати карту, щоб видалити властивість, а потім повернути новий елемент масиву.

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

12
Майте на увазі, що це
змінює

1
У цьому конкретному випадку явної returnзаяви не потрібно буде
Сандіп Кумар,

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

14

Якщо ви використовуєте underscore.js :

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

9

Рішення з використанням прототипів можливе лише тоді, коли ваші об’єкти однакові:

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

Але тоді це просто (і O(1)):

delete Cons.prototype.bad;

3

На мій погляд, це найпростіший варіант

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

3
питання стосувалося видалення поганого, а не збереження доброго. Якщо у ваших об’єктів є 10 полів для збереження та одне для видалення, вищевказане стає справді довгим для введення.
адріен

1

Ви можете стежити за цим, більш читабельним, не підвищеним очікуванням через не знайдений ключ:

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

0

Я запропоную використовувати Object.assignв forEach()циклі, щоб об'єкти копіювались і не впливали на вихідний масив об'єктів

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

0

Зараз це питання трохи застаріле, але я хотів би запропонувати альтернативне рішення, яке не змінює вихідні дані і вимагає мінімальних ручних зусиль:

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

Це все ще трохи менше, ніж ідеально, але підтримує певний рівень незмінності та має гнучкість для визначення кількох властивостей, які ви хочете видалити. (Пропозиції вітаються)


0

я спробував створити новий об'єкт, не видаляючи куль у Vue.js.

let data =this.selectedContactsDto[];

// selectedContactsDto [] = об'єкт зі списком об'єктів масиву, створених у моєму проекті

console.log (дані); нехай newDataObj = data.map (({groupsList, customFields, firstname, ... item}) => item); console.log ("newDataObj", newDataObj);


0

Щоб видалити деяку масу масиву об'єкта форми пари, використовується Postgres SQL як база даних, як у цьому прикладі:

Це об'єкт функції користувача, що повертає дані про користувача, ми повинні видалити ключ "api_secret" із рядків:

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

Вищевказана функція повертає нижче об'єкта як відповідь JSON раніше

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

Після додавання цього рядка responseObject._embedded[0].api_secret = undefinedце дає нижче результат як відповідь JSON:

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


0

Існує безліч бібліотек. Все залежить від того, наскільки складною є ваша структура даних (наприклад, розгляньте глибоко вкладені ключі)

Нам подобаються поля-об'єкти, оскільки вони також працюють із глибоко вкладеними ієрархіями (параметр збірки для полів api). На основі сканування об’єктів , щоб ви знали, що це швидко. Ось простий приклад коду

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


Не могли б ви пояснити своє рішення?
sg7,

Map - це нова структура даних у JavaScript ES6. Вкладене посилання може вам допомогти. hackernoon.com/what-you-should-know-about-es6-maps-dc66af6b9a1e
hk_y

це рішення не є хорошим, якщо у вас багато реквізиту.
Koop4,

Так! Намагався надати інший підхід.
hk_y
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.