Рекурсивная подгонка объекта JavaScript к определенной структуре - PullRequest
3 голосов
/ 11 октября 2019

У меня есть проблема, когда я не могу понять, как реализовать это в коде. Я думаю, что для этого мне придется использовать силу рекурсии, но я действительно борюсь с этим.

У меня есть этот объект (упрощенный для этого вопроса), где вложенные глубины могут быть неизвестны.

 const allValues = {
  features: {
    title: 'features',
    description: 'some features',
    fields: {
      featureA: false,
      featureB: true,
      featureC: true
    }
  },
  otherthings: {
    title: 'otherthings',
    description: 'otherthingsdescription',
    fields: {
      nestedotherthings: {
        title: 'nestedotherthings',
        description: 'nestedotherthingsdescription',
        fields: {
          againnested: {
            title: 'againsnested',
            description: 'againsnested',
            fields: {
              finallynestedvalue: 1
            }
          },
          againnested2: {
            title: 'againsnested2',
            description: 'againsnested2',
            fields: {
              finallynestedvalue: 200
            }
          }
        }
      }
    }
  }
}

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

  const expected_output = {
  features: {
    featureA: false,
    featureB: true,
    featureC: true
  },
  othertings: {
    nestedotherthings: {
      againnested: {
        finallynestedvalue: 1
      },
      againnested2: {
        finallynestedvalue: 2
      }
    }
  }
}

Что я пробовал:

 const output = _(allValues).mapValues((value, key) => flattenFields({}, value, key)).value()

function flattenFields(parent, current, key) {
  if (!current || !current.fields) {
    return current
  }

  return {
    ...parent,
    [key]: _(current.fields).mapValues((value, key) => flattenFields(current, value, key)).value()
  }
}

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

1 Ответ

3 голосов
/ 11 октября 2019

Вы можете использовать рекурсивный подход, проверив значения и если объект принимает свойство fields или значение. Затем перестройте новый объект.

function convert(object) {
    return Object.fromEntries(Object
        .entries(object)
        .map(([k, v]) => [k, v && typeof v === 'object' ? convert(v.fields) : v])
    );
}

var data = { features: { title: 'features', description: 'some features', fields: { featureA: false, featureB: true, featureC: true } }, otherthings: { title: 'otherthings', description: 'otherthingsdescription', fields: { nestedotherthings: { title: 'nestedotherthings', description: 'nestedotherthingsdescription', fields: { againnested: { title: 'againsnested', description: 'againsnested', fields: { finallynestedvalue: 1 } }, againnested2: { title: 'againsnested2', description: 'againsnested2', fields: { finallynestedvalue: 200 } } } } } } },
    result = convert(data);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
...