JavaScript通过使用另一个对象作为选择器来删除对象属性
我有这样的目标:JavaScript通过使用另一个对象作为选择器来删除对象属性,javascript,object,recursion,Javascript,Object,Recursion,我有这样的目标: var myObj = { first: { sub: { prop1: "some text", prop2: "some more text" }, sub2: { prop1: "Something", prop2: "Something2", } }, second: {
var myObj = {
first: {
sub: {
prop1: "some text",
prop2: "some more text"
},
sub2: {
prop1: "Something",
prop2: "Something2",
}
},
second: {
stuff: "More stuff...lots of stuff"
}
}
我试图通过使用另一个对象作为选择器来删除此对象的属性。例如:
var delSeletor = {
first: {
sub: {
prop2: ""
}
}
}
因此delete(delSelector,myObject)
应该返回:
var myObj = {
first: {
sub: {
prop1: "some text",
},
sub2: {
prop1: "Something",
prop2: "Something2",
}
},
second: {
stuff: "More stuff...lots of stuff"
}
}
请注意,我不是在寻找使用“.dot”选择器的解决方案,例如:
delete('first.sub.prop2',myObj)
,如图所示。您可以迭代对象选择器
,以获取要删除的键并进行检查
- 如果密钥不存在,则返回
- 如果选择器对象的属性是对象,则使用键再次调用delete函数
。否则,从源对象中删除密钥deleteKeys
函数删除键(对象、选择器){
Object.keys(选择器).forEach(函数(k){
如果(!(对象中的k)){
返回;
}
if(选择器的类型[k]=“对象”){
删除键(对象[k],选择器[k]);
}否则{
删除对象[k];
}
});
}
var myObj={first:{sub:{prop1:{some text],prop2:{some more text},sub2:{prop1:“Something”,prop2:“Something 2”,},第二:{stuff:{stuff:“more stuff…lot stuff”},
delSeletor={first:{sub:{prop2::}}};
删除键(myObj、delSeletor);
console.log(myObj)代码>
.as控制台包装{max height:100%!important;top:0;}
这是一个使用函数编程的版本,它使用map
和reduce
它递归地遍历对象并删除在对象上用表示删除的空字符串标记的键
function deleteKeys(deletions, obj) {
if (deletions === "") {
return null
}
return Object
.keys(obj)
.map(key => {
if (!(key in deletions)) {
// if the key is not in the object containing
// the keys to delete
return { [key]: obj[key] };
}
//recursively create a filtered object
const filteredObj = deleteKeys(deletions[key], obj[key])
// if that object is null, then return an empty object
// else return the filtered object
return filteredObj ? { [key]: filteredObj } : {}
})
// we now have an array of object that we need to merge together :)
.reduce((acc, obj) => Object.assign({}, acc, obj), {})
}
以下是我为编写此代码而运行的测试:
const cleanedObj = deleteKeys(
{ first: "" },
{ first: "", second: { hi: ["heelo"] }}
);
console.log(cleanedObj);
const cleanedObj2 = deleteKeys(
{ second: { hi: "" }},
{ first: "", second: { hi: ["heelo"] }}
);
console.log(cleanedObj2);
const cleanedObj3 = deleteKeys(
{ second: "" },
{ first: "", second: { hi: ["heelo"] }}
);
console.log(cleanedObj3);
这个解决方案值得注意的是,它是一个纯函数,这意味着它不会修改初始对象,而是返回一个新对象。FTW无副作用,我们现在用于此类数据处理任务。只要你把头绕在它身上,它就会非常强大。以下是您解决问题的方法
注:
- 首先,我们扫描第一个选择器对象并提取路径。然后我们使用路径删除相应的目标
- 这也适用于阵列,只需稍作修改
//const objectScan=require('object-scan');
常量修剪=(选择,输入)=>{
常量指针=对象扫描(['**']{
是的,
filterFn:({value})=>typeof value==='string'
})(sel);
返回对象扫描(针{
rtn:'计数',
filterFn:({parent,property})=>{
删除父项[属性];
}
})(输入);
};
const myObj={first:{sub:{prop1:{some text',prop2:{some more text'},sub2:{prop1:'Something',prop2:'Something 2'},第二:{stuff:'more stuff…lot of stuff'};
const delSeletor={first:{sub:{prop2:''}}};
console.log(prune(delSeletor,myObj));//返回删除计数
// => 1
console.log(myObj);
//=>{first:{sub:{prop1:{some text'},sub2:{prop1:'Something',prop2:'Something2'},第二:{stuff:'More stuff…lots stuff'}
。作为控制台包装{最大高度:100%!重要;顶部:0}
删除意味着相同的对象?选择器总是以根键开始吗?如果delSelector
是一个数组,不是更简单吗?ie[“first”、“sub”、“prop2”]
有点像xpath的工作原理。如果您可以使用一段代码将初始对象转换为点
符号,然后使用另一个线程中给出的删除
,会怎么样?这能回答您的问题吗?是的,这意味着从myObj中删除,是的,选择器总是从根键开始(在本例中首先),并按照正确的路径进行操作。@Halcyon&@atomrc我现在正在使用该解决方案,但我正试图找到更高效、更快速的工作解决方案,这将直接在对象级别上工作,而不是将对象选择器转换为数组或dot
selectorExcellent解决方案,并且初始测试显示了更好的性能。