删除数组中所有对象的属性
Posted
技术标签:
【中文标题】删除数组中所有对象的属性【英文标题】: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 是的,一般情况下没有什么比这更快了。
【参考方案1】:
使用 ES6,您可以解构每个对象以创建没有命名属性的新对象:
const newArray = array.map((dropAttr1, dropAttr2, ...keepAttrs) => keepAttrs)
【讨论】:
应用到最初的问题可能是const newArray = array.map(( bad, ...item ) => item);
这个非常推荐,因为它不会修改原始数组(不可变操作)
这应该是公认的答案,因为它返回一个新数组,而不是覆盖现有数组。
如果道具是动态的呢?你需要即时删除它吗?
@ИгорТашевски .map(( [prop]: _, ...keep ) => keep)
【参考方案2】:
唯一的其他方式是装饰性的,实际上是循环。
例如:
array.forEach(function(v) delete v.bad );
注意事项:
如果你想兼容 IE8,你需要a shim for forEach。正如你提到的原型,prototype.js 也是has a shim。delete
是最糟糕的 "optimization killers" 之一。使用它通常会破坏应用程序的性能。如果您想真正删除某个属性,则无法避免这种情况,但您通常可以将属性设置为 undefined
,或者只构建没有该属性的新对象。
【讨论】:
如果允许循环是“假的”,那么不会比循环好多少——也有一个内衬:Pfor(var i = 0; i < 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 => 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
<script src="https://bundle.run/object-fields@2.0.19"></script>
免责声明:我是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
(您正在使用的数组方法)混淆了。以上是关于删除数组中所有对象的属性的主要内容,如果未能解决你的问题,请参考以下文章