JavaScript - Как объединить сложный вложенный объект, используя другой в качестве ссылки для итерации? - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть объект с несколькими ключами в форме:

{
    '.[key1].[key2].[key3]': {},
    '.[key1].[key2].[key3].[key4]': {},
    '.[key1].[key2].[key3].[key5]': {},
}

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

Ниже приведен ссылочный объект

const invoiceShape = {
    'cfdi\\:CdfiRelacionados': {
      'tfd\\:CfdiRelacionado': {},
    },
    'cfdi\\:Emisor': {},
    'cfdi\\:Receptor': {},
    'cfdi\\:Conceptos': {
      'cfdi\\:Concepto': {
        'cfdi\\:Impuestos': {
          'cfdi\\:Traslados': {
            'cfdi\\:Traslado': {},
          },
          'cfdi\\:Retenciones': {
            'cfdi\\:Retencion': {},
          },
          'cfdi\\:InformacionAduanera': {},
          'cfdi\\:CuentaPredial': {},
          'cfdi\\:Parte': {
            'cfdi\\:InformacionAduanera': {},
          },
        },
      },
    },
    'cfdi\\:Complemento': {
      'tfd\\:TimbreFiscalDigital': {},
    },
    'cfdi\\:Addenda': {},
  };

Итак, мой объект выглядит следующим образом

const invoiceParsed = {
    '.cfdi\\:Conceptos.cfdi\\:Concepto.cfdi\\:Impuestos': {},
    '.cfdi\\:Conceptos.cfdi\\:Concepto.cfdi\\:Impuestos.cfdi\\:Traslados': {},
    '.cfdi\\:Conceptos.cfdi\\:Concepto.cfdi\\:Impuestos.cfdi\\:Retenciones': {},
}

Объект invoiceShape имеет пустые значения на ключах, но теперь этообъект invoiceParsed заполнен. Я хочу, чтобы он также заполнил invoiceShape , я выяснил, что при разборе каждого вложенного уровня разбивается символ "."в ключах invoiceParsed - более эффективный способ итерации по ссылочному объекту, но если я итерирую по ключу 'cfdi\\:Conceptos' во второй раз, я просто перезаписываю значение ключа, а не объединяю его

Я не публикую ни одного кода на итерации, потому что я хочу прочитать ваши идеи, алгоритмы или пакеты, которые вы использовали бы в качестве lodash, например

1 Ответ

0 голосов
/ 29 ноября 2018

Мне нравится Ramda для чего-то подобного, хотя part.lenses - еще один отличный инструмент для работы с глубоко вложенными данными.

Вот два рабочих решения.Первая использует несколько функций от Ramda.Второй - в основном ванильный JS с двумя функциями от Ramda:

const shape = {
  a: {
    b: {
      c: {}
    }
  },
  d: {
    e: {
      f: {
        g: {}
      }
    }
  },
  h: {}
}

const parsed = {
  'a': { v: 1 },
  'a.b': { v: 2 },
  'a.b.c': { v: 3 },
  'd': { v: 4 },
  'd.e': { v: 5 },
  'd.e.f': { v: 6 },
  'd.e.f.g': { v: 7 },
  'h': { v: 8 }
}

const fillShapeWithParsed = s =>
  R.pipe(
    R.toPairs,
    R.reduce(
      (acc, [k, v]) =>
        R.over(R.lensPath(k.split('.')), R.merge(v), acc),
        s
    )
  )

console.log(
  fillShapeWithParsed(shape)(parsed)
)

const merge = x => y => ({ ...y, ...x })

const fillShapeWithParsedVanilla = s => p =>
  Object.entries(p).reduce(
    (acc, [k, v]) =>
      R.over(R.lensPath(k.split('.')), merge(v), acc),
      s
  )

console.log(
  fillShapeWithParsedVanilla(shape)(parsed)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>

Для гибридного решения, использующего Ramda и part.lenses вместе, просто поменяйте строку в примере, который начинается R.over( с этого:

L.modify(k.split('.'), R.merge(v), acc)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...