使用 JavaScript 从对象中递归删除属性和值的最快方法是啥?
Posted
技术标签:
【中文标题】使用 JavaScript 从对象中递归删除属性和值的最快方法是啥?【英文标题】:Using JavaScript what's the quickest way to recursively remove properties and values from an object?使用 JavaScript 从对象中递归删除属性和值的最快方法是什么? 【发布时间】:2015-10-22 02:50:47 【问题描述】:我需要找到从对象中删除所有$meta
属性及其值的最快方法,例如:
"part_one":
"name": "My Name",
"something": "123",
"$meta":
"test": "test123"
,
"part_two": [
"name": "name",
"dob": "dob",
"$meta":
"something": "else",
"and": "more"
,
"name": "name",
"dob": "dob"
],
"$meta":
"one": 1,
"two": 2
鉴于$meta
属性可能位于对象中的任何位置,因此应该变为以下形式,因此可能需要某种形式的递归。
"part_one":
"name": "My Name",
"something": "123"
,
"part_two": [
"name": "name",
"dob": "dob"
,
"name": "name",
"dob": "dob"
]
任何帮助或建议将不胜感激!
谢谢!
【问题讨论】:
不要使用递归,而是制作对象的副本,省略您不想要的属性和值。关于 javascript 中递归的一般说明:它取决于浏览器的内存分配,这并不多,因此递归会占用大量资源,并且除非实施仔细的内存管理,否则不适用于大型数据集。 最快的方法是先自己实现,然后寻求帮助以使其更快。 您可以使用 for in 循环或更准确地说 for of --> developer.mozilla.org/en/docs/Web/JavaScript/Reference/… 来遍历对象的属性和值 【参考方案1】:一个简单的自调用函数就可以做到。
function removeMeta(obj)
for(prop in obj)
if (prop === '$meta')
delete obj[prop];
else if (typeof obj[prop] === 'object')
removeMeta(obj[prop]);
var myObj =
"part_one":
"name": "My Name",
"something": "123",
"$meta":
"test": "test123"
,
"part_two": [
"name": "name",
"dob": "dob",
"$meta":
"something": "else",
"and": "more"
,
"name": "name",
"dob": "dob"
],
"$meta":
"one": 1,
"two": 2
function removeMeta(obj)
for(prop in obj)
if (prop === '$meta')
delete obj[prop];
else if (typeof obj[prop] === 'object')
removeMeta(obj[prop]);
removeMeta(myObj);
console.log(myObj);
【讨论】:
直到 JS 有尾递归优化,这对于大对象来说是不安全的。对于具有循环引用的对象也是不安全的。 完美运行,如果您需要保留原始对象,请务必克隆对象。 我不认为它对我有用。如果那是一个对象,那么它只需要第一个属性。其他人呢?消除该特定道具后,它不会返回整个对象。或者我错过了什么?【参考方案2】:正如@floor 上面评论的那样:
JSON.parse(JSON.stringify(obj, (k,v) => (k === '$meta')? undefined : v))
【讨论】:
相反,将替换器作为参数提供给 stringify 调用,从而避免将这些属性序列化为以开头的字符串 警告此方法将从对象中删除不可序列化的内容,例如函数或 DOM 元素【参考方案3】:// Helper function
function removeProps(obj,keys)
if(Array.isArray(obj))
obj.forEach(function(item)
removeProps(item,keys)
);
else if(typeof obj === 'object' && obj != null)
Object.getOwnPropertyNames(obj).forEach(function(key)
if(keys.indexOf(key) !== -1)delete obj[key];
else removeProps(obj[key],keys);
);
// The object we want to iterate
var obj =
"part_one":
"name": "My Name",
"something": "123",
"$meta":
"test": "test123"
,
"part_two": [
"name": "name",
"dob": "dob",
"$meta":
"something": "else",
"and": "more"
,
"name": "name",
"dob": "dob"
],
"$meta":
"one": 1,
"two": 2
;
// Utilize the utility
removeProps(obj,['$meta']);
// Show the result
document.body.innerhtml = '<pre>' + JSON.stringify(obj,null,4) + '</pre>';
【讨论】:
在任何级别的纯 js 中实现这一点的聪明方法,谢谢!【参考方案4】:我使用 @Joseph Marikle
的引用函数在对象中的any level 中的any key 中创建了这个函数const _ = require("lodash");
const isObject = obj => obj != null && obj.constructor.name === "Object";
const removeAttrDeep = (obj, key) =>
for (prop in obj)
if (prop === key) delete obj[prop];
else if (_.isArray(obj[prop]))
obj[prop] = obj[prop].filter(k =>
return !_.isEmpty(removeAttrDeep(k, key));
);
else if (isObject(obj[prop])) removeAttrDeep(obj[prop], key);
return obj;
;
示例:
const _obj =
a: "b", b: "e", c: a: "a", b: "b", c: "c",
d: [ a: "3" , b: ["2", "3"] ];
console.log(removeAttrDeep(_obj, "b"));
【讨论】:
【参考方案5】:(抱歉,我还没有足够的声望点来直接评论。)
仅供参考,typeof null === 'object',因此在@joseph-marikle 提供的 removeMeta() 示例中,该函数将在 null 值上递归。
在此处阅读更多信息:why is typeof null "object"?
【讨论】:
【参考方案6】:这是一个函数,它需要一个字符串或一个字符串数组以递归方式删除(基于约瑟夫的回答):
// removes all propsToRemove (passed as an array or string), drilling down up to maxLevel times
// will modify the input and return it
du.removeAllPropsFromObj = function(obj, propsToRemove, maxLevel)
if (typeof maxLevel !== "number") maxLevel = 10
for (var prop in obj)
if (typeof propsToRemove === "string" && prop === propsToRemove)
delete obj[prop];
else if (propsToRemove.indexOf(prop) >= 0) // it must be an array
delete obj[prop];
else if (typeof obj[prop] === "object" && maxLevel>0)
du.removeAllPropsFromObj(obj[prop], propsToRemove, maxLevel-1);
return obj
【讨论】:
【参考方案7】:// recursively delete a key from anywhere in the object
// will mutate the obj - no need to return it
const deletePropFromObj = (obj, deleteThisKey) =>
if (Array.isArray(obj))
obj.forEach(element => deletePropFromObj(element, deleteThisKey))
else if (typeof obj === 'object')
for (const key in obj)
const value = obj[key]
if (key === deleteThisKey) delete obj[key]
else deletePropFromObj(value, deleteThisKey)
deletePropFromObj(obj, '$meta');
【讨论】:
以上是关于使用 JavaScript 从对象中递归删除属性和值的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章