简体   繁体   English

如何删除具有动态数量的属性且没有eval的嵌套Javascript对象中的键?

[英]How can I delete a key in a nested Javascript object with a dynamic number of properties and without eval?

I am looking to delete a specific key from a nested Javascript object based on a list of dynamic properties. 我正在基于动态属性列表从嵌套Javascript对象中删除特定键。 Here is an example of what I mean: 这是我的意思的示例:

This is a sample object: 这是一个示例对象:

employees: [
    {
        name: "John",
        id: 1234567890,
        salary: 60000
    },
    {
        name: "Jack",
        id: 0987654321,
        salary: 55000
    }
],
location: {
    building: {
        address: "111 Main St"
    }
}

I am looking to delete the address key when I am provided an array of ['location', 'building', 'address'] 当我提供['location', 'building', 'address']数组时,我想删除address

When I say "dynamic" I mean that I could also be provided with an array of ['employees', 1] so I cannot rely on a set number of nested properties. 当我说“动态”时,我的意思是也可以给我提供一个['employees', 1]数组,所以我不能依赖于一定数量的嵌套属性。

The only approach that works for me right now is to use the dreaded eval , which is not a permanent solution since the Javascript objects that I am reading are written by users. 目前对我有用的唯一方法是使用可怕的eval ,这不是永久性的解决方案,因为我正在读取的Javascript对象是由用户编写的。

let jsObject = ... // the object shown above
let properties = ['location', 'building', 'address']
let evalString = ''
for (let i = 0; i < properties.length; i++){
    evalString += '[\''+properties[i]+'\']'
}
eval('delete jsObject'+evalString)

What is an alternative to eval that will accomplish this same goal? 什么是替代eval将实现此相同的目标?

You can break your array into everything except the last element, get a reference to that and the call delete on the object using the last element. 您可以将数组分解为除最后一个元素以外的所有内容,获取对该元素的引用,并使用最后一个元素对对象进行调用delete You can use reduce to easily build the object reference. 您可以使用reduce轻松构建对象引用。 You need to be careful with arrays because you can't use delete without leaving an empty slot — delete doesn't change the length. 您需要注意数组,因为您不能在不留空位的情况下使用delete - delete不会更改长度。

Here's the basic idea: 这是基本思想:

 function deleteProp(obj, keys){ let prop = keys.pop() // get last key let c = keys.reduce((a, c) => a[c], obj) // get penultimate obj if (Array.isArray(c)) c.splice(prop, 1) // if it's an array, slice else delete c[prop] // otherwise delete } // Delete address let obj = {employees: [{name: "John",id: 1234567890,salary: 60000},{name: "Jack",id: 0987654321,salary: 55000}],location: {building: {address: "111 Main St"}}} deleteProp(obj, ['location', 'building', 'address']) console.log(obj) //Delete employee 1 obj = {employees: [{name: "John",id: 1234567890,salary: 60000},{name: "Jack",id: 0987654321,salary: 55000}],location: {building: {address: "111 Main St"}}} deleteProp(obj, ['employees', 1]) console.log(obj) //Delete employee 1 id obj = {employees: [{name: "John",id: 1234567890,salary: 60000},{name: "Jack",id: 0987654321,salary: 55000}],location: {building: {address: "111 Main St"}}} deleteProp(obj, ['employees', 1, 'id']) console.log(obj) 

This method accepts an object and an array of properties, and removes the inner most property as required 此方法接受一个对象和一个属性数组,并根据需要删除最里面的属性

function remove(obj, props) {
    delete props.slice(0, -1).reduce((init, curr) => init && init[curr], obj)[[...props].pop()];
}

You could reduce the object by the keys and save the last key for deleting the object with that key. 您可以通过键减少对象,并保存最后一个键以使用该键删除对象。

 function deleteKey(object, keys) { var last = keys.pop(); delete keys.reduce((o, k) => o[k], object)[last]; return object; } var object = { employees: [{ name: "John", id: '1234567890', salary: 60000 }, { name: "Jack", id: '0987654321', salary: 55000 }], location: { building: { address: "111 Main St" } } }; console.log(deleteKey(object, ['location', 'building', 'address'])); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Here is a sample that i'm sure could be trimmed down a bit but it explains each step and you should be able to see whats happening in it: 这是一个我敢肯定可以减少一点的示例,但是它解释了每个步骤,您应该能够看到其中发生了什么:

 let jsObject = { employees: [{ name: "John", id: 1234567890, salary: 60000 }, { name: "Jack", id: 0987654321, salary: 55000 } ], location: { building: { address: "111 Main St" } } }; let properties = ['location', 'building', 'address']; // we use this to traverse the object storing the parent let parent = null; // run over each property in the array for (let i = 0; i < properties.length; i++) { // check if this is the last property and we have the parent object if (i + 1 == properties.length && parent) delete parent[properties[i]]; // just delete the property from the object else if (parent === null) parent = jsObject[properties[i]] // set the initial parent else parent = parent[properties[i]] // set the parent to the property in the existing object } // log the output console.log(jsObject); 

You are going to want to throw error handling and checks to make sure you don't end up outside the object as well. 您将要抛出错误处理和检查,以确保您也不会出现在对象之外。

Navigate to the object that contains the property you want to delete, then delete it: 导航到包含要删除的属性的对象,然后将其删除:

 let jsObject = { employees: [ { name: "John", id: 1234567890, salary: 60000 }, { name: "Jack", id: 0987654321, salary: 55000 } ], location: { building: { address: "111 Main St" } } }; let properties = ['location', 'building', 'address']; let innerMost = jsObject; for (let i = 0; i < properties.length - 1; i++) { if (typeof innerMost !== "object" || innerMost === null) { innerMost = null; break; } innerMost = innerMost[properties[i]]; }; if ( innerMost !== null && typeof innerMost === "object" && properties.length > 0 && innerMost.hasOwnProperty(properties[properties.length - 1]) ) { delete innerMost[properties[properties.length - 1]]; console.log(jsObject); } else console.log("Invalid path"); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在javascript中的嵌套对象中对键的顺序进行排序? - How can I sort the order of key in a nested object in javascript? 如何删除 javascript 中的嵌套属性 - how to delete nested properties in javascript 使用不带eval的字符串键访问或创建嵌套的JavaScript对象 - Accessing or creating nested JavaScript objects with string key without eval 如何检查是否存在具有相同密钥的 object 并使用数组(javascript)中的相同密钥和不同属性进行更新? - How can I check if there's an object with a same key and update with a same key and different properties in array(javascript)? 您可以在不知道 Javascript 中的键的情况下跳过嵌套对象中的级别吗? - Can you skip a level in a nested object without knowing the key in Javascript? 如何从 object 中删除密钥? - How can i delete key from the object? 对象属性动态删除 - Object properties dynamic delete 如何遍历JavaScript对象的深层嵌套属性? - How do I loop through deeply nested properties of a JavaScript object? 如何删除可以任意嵌套的JavaScript对象中的某些内容? - How to delete something in a JavaScript object that can be nested arbitrarily deep? 如何使用 Lodash 或普通 javascript 使用动态过滤器过滤嵌套的 object? - How can I filter a nested object with dynamic filters using Lodash or plain javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM