Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/454.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用es6递归更新对象_Javascript_Recursion_Ecmascript 6 - Fatal编程技术网

Javascript 使用es6递归更新对象

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 }]

我在一个数据树中有很多子对象,我想用es6语法递归地将toggle值更新为true,然后返回更新后的数据树

对象看起来像这样

{
    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 : []
//         }
//       ]
//     }
//   ]
// }