рекурсивно создать вложенный объект из другого объекта в javascript - PullRequest
0 голосов
/ 16 марта 2020

Я новичок в программировании, и я работал над вопросом, который меня беспокоит некоторое время.

Я хочу рекурсивно создать вложенный объект из другого вложенного объекта в javascript,

ниже приведен пример данных для ввода, но в реальной ситуации я не знаю, насколько глубоким будет этот объект.

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

это результат, который я хочу (см. Число четное или нечетное четное = истинное, нечетное = ложное)

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
        }
    });
}

Я буду очень признателен, если кто-то может помочь мне в этом.

Ответы [ 3 ]

1 голос
/ 16 марта 2020

Вместо того, чтобы что-то поменять, сделайте что-то более функциональным и верните новый объект:

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

В основном мы проверяем, является ли объект объектом (используя typeof), и go глубже, если это так. В противном случае мы проверяем, является ли оно нечетным или четным.

1 голос
/ 17 марта 2020

Вы также можете думать об этом более обобщенно, написав функцию, которая будет применять ваше преобразование ко всем конечным узлам вашего объекта, а затем вызывать ее с помощью функции 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)
1 голос
/ 16 марта 2020

Вместо return {[element]: result}; перезаписать значение и вернуть мутированный объект из функции после того, как l oop:

заметит, что это приведет к мутации исходного объекта, если вы хотите сохранить его, сделать копию:

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...