Javascript 使用es6递归更新对象
我在一个数据树中有很多子对象,我想用es6语法递归地将toggle值更新为true,然后返回更新后的数据树 对象看起来像这样Javascript 使用es6递归更新对象,javascript,recursion,ecmascript-6,Javascript,Recursion,Ecmascript 6,我在一个数据树中有很多子对象,我想用es6语法递归地将toggle值更新为true,然后返回更新后的数据树 对象看起来像这样 { name: "Misc", toggled: true, children: [{ name: "Apple", toggled:false children: [{ name: "banana", toggled:false }]
{
name: "Misc",
toggled: true,
children: [{
name: "Apple",
toggled:false
children: [{
name: "banana",
toggled:false
}]
}]
}
等等
有什么想法吗,谢谢我不知道你是否想要,但我试过了
var obj = {
name: "Misc",
toggled: true,
children: [{
name: "Apple",
toggled:false,
children: [{
name: "banana",
toggled:false
}]
}]
};
var toggleToTrue = function(obj){
if (!obj) { return false; }
obj.toggled = true;
if (!obj.children) { return false; }
var childs = obj.children;
for (var i in childs){
toggleToTrue(childs[i]);
}
};
toggleToTrue(obj);
console.log(obj);
您可以将以下内容用于递归解决方案,该解决方案不改变原始对象,不向没有这些属性的对象添加属性(如果对象没有属性,则添加<代码>切换代码>),并且可以由调用方配置以更改某些行为:
var obj={
名称:“杂项”,
切换:对,
儿童:[{
名称:“苹果”,
切换为:false,
儿童:[{
名称:“香蕉”,
切换:false
}]
}]
};
const changeProp=(shouldSet、set、doRecursive、rec)=>calcValue=>(obj)=>{
常数切换=o=>{
if(shouldSet(o)){
返回集({…o},calcValue(o));
}
返回o;
};
返回(!doRecursive(obj))
?开关(obj)
:rec(切换(obj)、changeProp(shouldSet、set、doRecursive、rec)(计算值))
};
const hasChild=o=>(o.hasOwnProperty(“children”)和&Array.isArray(o.children));
const setRecursive=(o,rec)=>({
……哦,
儿童:o.children.map(rec)
});
//设置为“真”
console.log(
更改道具(
o=>(typeof o.toggled==“boolean”),//应设置函数
(o,value)=>{o.toggled=value;返回o;},//set函数
hasChild,//是否执行递归?
setRecursive//递归集
)(()=>true)//基于对象计算值(值始终为true)
(obj)
);
//大写名称
console.log(
更改道具(
o=>(typeof o.name==“string”),//应设置函数
(o,value)=>{o.name=value;返回o;},//set函数
hasChild,//是否执行递归?
setRecursive//递归集
)((o)=>o.name.toUpperCase())//基于对象计算值(名称为大写)
(obj)
);代码>为您的{name,toggled,children}类型创建一个模块
-这里我们称我们的节点
const Node =
{ make : (name = "", toggled = false, children = []) =>
({ name, toggled, children })
, toggle : (node) =>
Node.make (node.name, !node.toggled, node.children)
, toggleAll : (node) =>
Node.make (node.name, !node.toggled, node.children.map (Node.toggleAll))
}
请注意,toggle
和toggleAll
不会改变原始输入,而是始终创建一个新节点
const n =
Node.make ("foo", true)
console.log (n, Node.toggle (n), n)
// { name: 'foo', toggled: true, children: [] }
// { name: 'foo', toggled: false, children: [] }
// { name: 'foo', toggled: true, children: [] }
我们可以直接在您的数据
上使用它来切换所有切换的
字段
const data =
{ name : "Misc"
, toggled : true
, children :
[ { name : "Apple"
, toggled : false
, children :
[ { name : "banana"
, toggled : false
, children : []
}
]
}
]
}
console.log (Node.toggleAll (data))
// { name : "Misc"
// , toggled : false <--- toggled
// , children :
// [ { name : "Apple"
// , toggled : true <--- toggled
// , children :
// [ { name : "banana"
// , toggled : true <--- toggled
// , children : []
// }
// ]
// }
// ]
// }
我想递归地将切换值更新为true
如果要将所有切换的设置为特定值,可以为其编写特定函数
const Node =
{ ...
, toggleAllOn : (node) =>
Node.make (node.name, true, node.children.map (Node.toggleAllOn))
}
或者,我们可以使用参数使原始的Node.toggle
和Node.toggleAll
更灵活,而不是制作许多特定的函数
const TOGGLE =
Symbol ()
const Node =
{ make : (name = "", toggled = false, children = []) =>
({ name, toggled, children })
, toggle : (node, value = TOGGLE) =>
Node.make ( node.name
, value === TOGGLE ? !node.toggled : Boolean (value)
, node.children
)
, toggleAll : (node, value = TOGGLE) =>
Node.make ( node.name
, value === TOGGLE ? !node.toggled : Boolean (value)
, node.children.map (n => Node.toggleAll (n, value))
)
}
现在,我们可以使用node.toggle(n)
切换节点n
,或者使用node.toggle(n,true)
或node.toggle(n,false)
程序演示
const切换=
符号()
常量节点=
{make:(name=”“,toggled=false,children=[])=>
({name,toggled,children})
,切换:(节点,值=切换)=>
Node.make(Node.name
,值===切换?!节点。切换:值
,node.children
)
,toggleAll:(节点,值=切换)=>
Node.make(Node.name
,值===切换?!节点。切换:值
,node.children.map(n=>node.toggleAll(n,值))
)
}
常量数据=
Node.make(“杂项”
是的
,[Node.make(“苹果”
,错
,[Node.make(“香蕉”,假)]
)
]
)
//显示原件
console.log(“原始”,数据)
//仅切换此节点
console.log('toggle',Node.toggle(数据))
//切换此节点和所有子节点
console.log('toggleAll',Node.toggleAll(数据))
//将此节点和所有子节点设置为true
console.log('toggleAll true',Node.toggleAll(数据,true))
//检查原始数据是否未发生变异(确定!)
console.log('original',data)
礼貌的做法是,在你请别人为你做这项工作之前,先做一些努力和研究。。。尝试通过递归方式搜索对象javascript@MatthewBrent我没有找到任何是es6的东西,更新了以前的数据,没有提取它。否则,我不会发布。es6或多或少只是语法上的差异。不要同时学习两件事-用es5编写-我建议使用array.prototype.map迭代对象数组以开始学习。不要就地编辑对象,而是生成一个新对象并从函数中返回该对象如何将其转换为字符串,然后替换所有切换:true to toggled:false,然后将字符串转换回json?@sumit一部分人认为这是一个可怕的想法,但另一部分人认为这很酷我建议不要在放置,但在通过对象递归并返回时创建一个新对象。是的,您是真的。我只知道他想更新当前项。一个6进制的部分curry函数应该表明可能有更好的方法。。。
const TOGGLE =
Symbol ()
const Node =
{ make : (name = "", toggled = false, children = []) =>
({ name, toggled, children })
, toggle : (node, value = TOGGLE) =>
Node.make ( node.name
, value === TOGGLE ? !node.toggled : Boolean (value)
, node.children
)
, toggleAll : (node, value = TOGGLE) =>
Node.make ( node.name
, value === TOGGLE ? !node.toggled : Boolean (value)
, node.children.map (n => Node.toggleAll (n, value))
)
}
const n =
Node.make ("foo", true)
console.log (n, Node.toggle (n, true), Node.toggle (n), n)
// { name: 'foo', toggled: true, children: [] } <--- original
// { name: 'foo', toggled: true, children: [] } <--- already true; no change
// { name: 'foo', toggled: false, children: [] } <--- toggled
// { name: 'foo', toggled: true, children: [] } <--- immutable
const allTrue =
Node.toggleAll (data, true)
console.log (allTrue)
// { name : "Misc"
// , toggled : true <--- same value
// , children :
// [ { name : "Apple"
// , toggled : true <--- set to true
// , children :
// [ { name : "banana"
// , toggled : true <--- set to true
// , children : []
// }
// ]
// }
// ]
// }