Javascript 递归跟踪具有结束值的嵌套对象关键点

Javascript 递归跟踪具有结束值的嵌套对象关键点,javascript,recursion,Javascript,Recursion,给定如下形状的对象(可能具有未知数量的嵌套属性) const主题={ 字体:{ 主要:“Arial”, 第二名:“Helvetica” }, 颜色:{ 小学:"绿色",, 中学:"红色",, }, 保证金:{ 小:“0.5雷姆”, 中等:“1rem”, 大:“1.5雷姆” } } 我正在努力实现以下目标: 递归循环,直到我找到一个不是对象的值 当我点击这个值时,我希望能够访问所有指向它的键,以及结束值 如下所示: ['font','primary','Arial' ['fonts','seco

给定如下形状的对象(可能具有未知数量的嵌套属性)

const主题={
字体:{
主要:“Arial”,
第二名:“Helvetica”
},
颜色:{
小学:"绿色",,
中学:"红色",,
},
保证金:{
小:“0.5雷姆”,
中等:“1rem”,
大:“1.5雷姆”
}
}
我正在努力实现以下目标:

  • 递归循环,直到我找到一个不是对象的值
  • 当我点击这个值时,我希望能够访问所有指向它的键,以及结束值
  • 如下所示:

    ['font','primary','Arial'

    ['fonts','secondary']'Helvetica'

    ['colors','primary']'green'

    等等


    我尝试了各种不同的尝试,但困扰我的是,如何跟踪这些键,并在再次调用原始循环时重置它们 可以采用递归方法检查对象,并将嵌套的子结果映射到最终结果

    const
    GetPaths=object=>object
    .条目(对象)
    .减少((r[k,v])=>{
    if(v&&typeof v=='object'){
    r、 push(…getPaths(v).map([p,v])=>[k,…p],v]);
    }否则{
    r、 推力([[k],v]);
    }
    返回r;
    }, []),
    主题={字体:{primary:'Arial',secondary:'Helvetica'},颜色:{primary:'green',secondary:'red'},边距:{小的:'0.5rem',中的:'1rem',大的:'1.5rem'};
    log(getPaths(主题))
    
    .as控制台包装{max height:100%!important;top:0;}
    这里是另一种方法

    您可以创建一个函数,该函数使用
    for of循环对作为参数传递的对象的键进行迭代。然后将当前密钥推入临时保存密钥的数组。然后,检查当前键是否具有非对象的值。如果此条件为true,则将对象推入在函数外部创建的数组中,该数组将当前键的值作为键,其值应为包含指向当前键值的所有键的数组

    如果当前键的值不是对象,则递归调用该函数并重复该过程

    p.S:我使用了以下输出格式

    [ { "Arial": [ "fonts", "primary" ] }, { "Helvetica": [ "fonts", "primary" ] } ]
    
    const主题={
    字体:{primary:'Arial',secondary:'Helvetica'},
    颜色:{primary:'绿色',secondary:'红色'},
    边距:{小:'0.5rem',中:'1rem',大:'1.5rem'}
    };
    常量keysArr=[];
    函数createKeyPath(obj,tempkysarr=[])){
    for(对象键(obj)的常数k){
    //在临时数组中按当前键
    tempkysarr.push(k);
    if(对象的类型[k]!=“对象”){
    //在keysArr中推送新对象
    keysArr.push({[obj[k]]:[…tempKeysArr]});
    //从临时密钥数组中删除最后一个密钥
    tempkysarr.pop();
    }否则{
    createKeyPath(obj[k],TempKeyArr);
    //重置tempKeysArr
    tempkysarr=[];
    }
    }
    }
    createKeyPath(主题);
    console.log(keysArr)
    
    .as console wrapper{max height:100%!important;top:0;}
    非常感谢您的回复,您的回复真的帮助了我达到了目的,我最终得出了以下结论:

    const setCSSVars=(对象:{[key:string]:any},堆栈:string[]=[])=>{
    Object.entries(obj.forEach)([key,value])=>{
    if(typeof value==='object'&&value!==null){
    setCSSVars(值,[…堆栈,键])
    }否则{
    document.documentElement.style.setProperty(
    `--主题-${stack.join('-')}-${key}`,
    价值
    )
    }
    })
    }
    
    另一种简单的递归方法如下所示:

    constpathcentries=(obj)=>
    对象(obj)==obj
    ? Object.entries(obj).flatMap(
    ([k,x])=>pathEntries(x).map([p,v])=>[[k,…p],v])
    ) 
    :[],obj]]
    常量主题={字体:{primary:'Arial',secondary:'Helvetica'},颜色:{primary:'green',secondary:'red'},边距:{small:'0.5rem',medium:'1rem',large:'1.5rem'}
    console.log(路径条目(主题))

    .as console wrapper{max height:100%!important;top:0}
    您想要单个值的路径还是所有值及其路径?所有路径和值都是我想要的!