从 javascript 中的其他对象递归创建嵌套对象

recursively create a nested object from other object in javascript

我是编程新手,正在处理一个困扰我一段时间的问题。

我想从 javascript、

中的另一个嵌套对象递归创建嵌套对象

下面是输入的示例数据,但在实际情况下,我不知道这个对象有多深。

nums = {
    Obj:{
        x1:{
            x11:43,
            x12:4,
            x13:612
        },
        x2:{
            x21:4,
            x22:7,
        },
        x3:2,
    }}

这就是我想要的结果(看数字是偶数还是奇数,even=true,odd=false)

res = {
    Obj:{
        x1:{
            x11:false,
            x12:true,
            x13:true
        },
        x2:{
            x21:true,
            x22:false,
        },
        x3:true,
    }}

这是我的代码

const nums = {
    Obj:{
        x1:{
            x11:43,
            x12:4,
            x13:612
        },
        x2:{
            x21:4,
            x22:7,
        },
        x3:2,
    }
}
const res ={};

getResult(nums);

console.log(res);

function getResult(x){
    Object.keys(x).forEach(element => {
        if(isNaN(x[element])){
            res[element]=getResult(x[element]);
        } else {
            let result = (x[element] % 2 < 1)? true:false;
            return {[element]: result}; // this is where I don't know what to, I try to return a object, 
                                        //  but it gives{x1: undefined, x2: undefined, Obj: undefined}
                                        //
                                        // if I change to "return res[element]=result"
                                        // every sub-Object will add under the same level
        }
    });
}

如果有人能帮助我,我将不胜感激。

而不是 return {[element]: result};,覆盖值,return 循环后函数中的变异对象:

请注意,这会改变原始对象,如果您想保留它,请复制一份:

const copy = JSON.parse(JSON.stringify(nums));

const nums = {
  Obj: {
    x1: {
      x11: 43,
      x12: 4,
      x13: 612
    },
    x2: {
      x21: 4,
      x22: 7,
    },
    x3: 2,
  }
}
const res = {};
const copy = JSON.parse(JSON.stringify(nums));

getResult(copy);

console.log(res);

function getResult(x) {
  Object.keys(x).forEach(element => {
    if (isNaN(x[element])) {
      res[element] = getResult(x[element]);
    } else {
      let result = (x[element] % 2 < 1) ? true : false;
      x[element] = result; // overwrite the number with true or flse
    }
  });
  return x; // return the mutated object
}

与其改变一些东西,不如让一些东西变得更实用,return 一个新对象:

const getResults = o => typeof o === "object"
    ? Object.keys(o).reduce((a, k) => ({ ...a, [k]: getResults(o[k]) }), {})
    : o % 2 === 1;

基本上我们检查对象是否是一个对象(使用 typeof),如果是则更深入。否则我们检查它是奇数还是偶数。

您也可以更一般地考虑这一点,编写一个函数,将您的转换应用于对象的所有叶节点,然后使用 isEven 函数调用它。这是一种技巧:

const mapLeaves = (fn) => (tree) =>
  typeof tree == "object"
    ? Object .fromEntries (Object .entries (tree) .map (
        ([k, v]) => [k, mapLeaves (fn) (v)]
      ))
    : fn (tree)
 
const isEven = (n) => n % 2 == 0

const nums = {Obj: {x1: {x11: 43, x12: 4, x13: 612}, x2: {x21: 4, x22: 7}, x3: 2}}

console .log (
  mapLeaves (isEven) (nums)
)

当然 mapLeaves (isEven) 是一个可以应用于多个对象的可重用函数。

这不处理数组。创建一个将此应用于数组条目的 mapLeaves 版本只会稍微复杂一些:

const mapLeaves = (fn) => (tree) =>
  Array .isArray (tree)
    ? tree .map (x => mapLeaves (fn) (x))
  : typeof tree == "object"
    ? Object .fromEntries (Object .entries (tree) .map (
        ([k, v]) => [k, mapLeaves (fn) (v)]
      ))
  : fn (tree)