【问题标题】:Remove property for all objects in array删除数组中所有对象的属性
【发布时间】:2013-08-10 14:45:46
【问题描述】:

我想从数组中的每个对象中删除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 或其他东西。我不知道。想法?

【问题讨论】:

  • 没关系,其他方式不能低于线性 O(n)。无论您使用什么,都需要访问您的所有数组元素
  • 原型?那会有什么帮助?还是所有这些对象都是同一个构造函数的实例并共享bad 的共同值?
  • @Bergi 我想知道他们指的是prototypeJS,还是Array原型,dystroy就是例子
  • 我不确定您是否应该在循环之前将 array.length 存储在变量中。我敢肯定,如果您进行分析,您会发现这不值得痛苦。
  • @ZackArgyle 是的,一般情况下没有什么比这更快了。

标签: javascript javascript-objects


【解决方案1】:

使用 ES6,您可以解构每个对象以创建没有命名属性的新对象:

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

【讨论】:

  • 应用到最初的问题可能是const newArray = array.map(({ bad, ...item }) =&gt; item);
  • 这个非常推荐,因为它不会修改原始数组(不可变操作)
  • 这应该是公认的答案,因为它返回一个新数组,而不是覆盖现有数组。
  • 如果道具是动态的呢?你需要即时删除它吗?
  • @ИгорТашевски .map(({ [prop]: _, ...keep }) =&gt; keep)
【解决方案2】:

唯一的其他方式是装饰性的,实际上是循环。

例如:

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

注意事项:

  • 如果你想兼容 IE8,你需要a shim for forEach。正如你提到的原型,prototype.js 也是has a shim
  • delete 是最糟糕的 "optimization killers" 之一。使用它通常会破坏应用程序的性能。如果您想真正删除某个属性,则无法避免这种情况,但您通常可以将属性设置为 undefined,或者只构建没有该属性的新对象。

【讨论】:

  • 如果允许循环是“假的”,那么不会比循环好多少——也有一个内衬:P for(var i = 0; i &lt; array.length ) delete array[i].bad
  • @Esailija 取决于。我喜欢使用forEach,因为我发现代码更具表现力(而且我很久以前就不再担心 IE)。
  • 它们都没有以完全不同的方式表达“删除此数组中所有对象的不良属性”。 forEach 本身是通用的并且在语义上没有意义,就像 for 循环一样。
  • @Esailija 我同意。这就是为什么我精确地说它是“化妆品”。我的回答不是很清楚吗?
  • 不幸。我会坚持使用通常比 forEach 更快的 for 循环。真的......谁在乎IE8。感谢您的帮助。
【解决方案3】:

我更喜欢使用 map 删除属性,然后返回新的数组项。

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

【讨论】:

  • 请注意,这会改变原始数组
  • 在这种特殊情况下,不需要明确的return 语句
  • array.forEach(v =&gt; delete v.bad);
【解决方案4】:

如果你使用underscore.js

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

【讨论】:

  • 据我所知,_.omit 正在 Lodash v5 中被删除
【解决方案5】:

在我看来这是最简单的变体

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

【讨论】:

  • 问题是关于去除坏的,而不是保留好的。如果您的对象有 10 个要保留的字段和一个要删除的字段,那么上面的输入会变得很长。
【解决方案6】:

您可以按照这个,更易读,而不是由于找不到密钥而提高期望:

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

【讨论】:

    【解决方案7】:

    只有当您的对象相似时,才有可能使用原型解决方案:

    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;
    

    【讨论】:

      【解决方案8】:

      ES6 中的最短路径:

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

      【讨论】:

        【解决方案9】:

        var array = [{"bad": "something", "good":"something"},{"bad":"something", "good":"something"}];
        
        const cleanArray = array.map(item=>{
          delete item.bad
          return item
        })
        console.log(cleanArray)

        【讨论】:

          【解决方案10】:

          这个问题现在有点老了,但我想提供一种替代解决方案,它不会改变源数据并且需要最少的人工:

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

          它仍然不够完美,但保持了一定程度的不变性,并且可以灵活地命名您要删除的多个属性。 (欢迎提出建议)

          【讨论】:

            【解决方案11】:

            我建议在forEach() 循环中使用Object.assign,以便复制对象并且不影响原始对象数组

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

            【讨论】:

              【解决方案12】:

              ES6:

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

              【讨论】:

                【解决方案13】:

                通过减少:

                const newArray = oldArray.reduce((acc, curr) => {
                  const { remove_one, remove_two, ...keep_data } = curr;
                  acc.push(keep_data);
                  return acc;
                }, []);
                

                【讨论】:

                  【解决方案14】:

                  这对我很有效!

                  export function removePropertiesFromArrayOfObjects(arr = [], properties = []) {
                  return arr.map(i => {
                      const newItem = {}
                      Object.keys(i).map(key => {
                          if (properties.includes(key)) { newItem[key] = i[key] }
                      })
                      return newItem
                  })
                  }
                  

                  【讨论】:

                    【解决方案15】:

                    我尝试在不删除 Vue.js 中的列的情况下创建一个新对象。

                    let data =this.selectedContactsDto[];

                    //selectedContactsDto[] = 包含在我的项目中创建的数组对象列表的对象

                    console.log(数据); 让 newDataObj= data.map(({groupsList,customFields,firstname, ...item }) => item); console.log("newDataObj",newDataObj);

                    【讨论】:

                      【解决方案16】:

                      要删除一些键值对形式的对象数组,使用 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"
                                  }
                              ]
                          }
                      

                      【讨论】:

                      • 它返回 null 到数组
                      • 如果可能,请分享您的代码示例。它有助于理解问题
                      【解决方案17】:

                      那里有很多图书馆。这完全取决于您的数据结构有多复杂(例如考虑深度嵌套的键)

                      我们喜欢object-fields,因为它也适用于深度嵌套的层次结构(为 api 字段参数构建)。这是一个简单的代码示例

                      // 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}
                      &lt;script src="https://bundle.run/object-fields@2.0.19"&gt;&lt;/script&gt;

                      免责声明:我是object-fields的作者

                      【讨论】:

                        【解决方案18】:

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

                        【讨论】:

                        • 您能解释一下您的解决方案吗?
                        • Map 是 JavaScript ES6 中的一种新数据结构。附加的链接可能会对您有所帮助。 hackernoon.com/what-you-should-know-about-es6-maps-dc66af6b9a1e
                        • 如果你的物品中有很多道具,这个解决方案并不好。
                        • 是的!试图提供不同的方法。
                        • 在您的评论中,您将Map(您未使用的数据结构)与Array.prototype.map(您正在使用的数组方法)混淆了。
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-12-14
                        • 2019-01-14
                        • 2013-05-05
                        • 1970-01-01
                        • 2021-02-24
                        • 2021-04-17
                        相关资源
                        最近更新 更多