首页 > 解决方案 > 如何递归嵌套对象值,以使父对象包含相应的命名集合?

问题描述

好的,首先:如果我可以用一种不那么笨拙的方式来表达我的问题,我会这样做的。

我正在努力描述如何描述我正在尝试做的事情。

目标

我正在尝试迭代一个对象(特别colors是默认TailwindCss配置中的对象),以生成可以拉入 nunjucks 模板的令牌列表。事实证明,这比我预期的更具挑战性。

我可能缺少一些基本的东西,但我不知道我不知道什么,你知道吗?

我有以下函数,它只遍历颜色对象:

const tailwindSrc = require("../node_modules/tailwindcss/defaultConfig.js");
const colors = tailwindSrc.theme.colors;

const iterateObject = function (object) {
    let tokenList = [];
    Object.keys(object).forEach((key) => {
        Object.keys(object[key]).forEach((subkey) => {
            tokenList.push({
                token: {
                collectionKey: key,
                key: subkey,
                value: object[key][subkey],
                },
            });
        });
    });
    return tokenList;
  };

  iterateObject(colors);

这是我当前结果的代表性部分

{ token: { collectionKey: 'gray', key: '50',  value: '#f9fafb' } },
{ token: { collectionKey: 'gray', key: '100', value: '#f3f4f6' } },
{ token: { collectionKey: 'gray', key: '200', value: '#e5e7eb' } },
{ token: { collectionKey: 'gray', key: '300', value: '#d1d5db' } },
{ token: { collectionKey: 'gray', key: '400', value: '#9ca3af' } },
{ token: { collectionKey: 'gray', key: '500', value: '#6b7280' } },
{ token: { collectionKey: 'gray', key: '600', value: '#4b5563' } },
{ token: { collectionKey: 'gray', key: '700', value: '#374151' } },
{ token: { collectionKey: 'gray', key: '800', value: '#1f2937' } },
{ token: { collectionKey: 'gray', key: '900', value: '#111827' } }

但我希望gray“集合”的值本身就是一个包含其他两个名称-值对的对象。

有点像下面这样,我猜。我根本没有挂在下面的结构上;只是试图或多或少地说明我需要如何对事物进行分组。

{
  token: { 
      collectionKey: 'gray',
      collectionEntries: {
          item: { key: '100', value: '#f3f4f6' }
          item: { key: '200', value: '#e5e7eb' }
          item: { key: '300', value: '#d1d5db' }
          item: { key: '400', value: '#9ca3af' }
          item: { key: '500', value: '#6b7280' }
          item: { key: '600', value: '#4b5563' }
          item: { key: '700', value: '#374151' }
          item: { key: '800', value: '#1f2937' }
          item: { key: '900', value: '#111827' }
      }
  }
}

在过去的两天里,我大概做了 8 到 10 次尝试来完成我所追求的目标。到目前为止没有骰子。

在我看来,我没有足够深入地递归来完成我想要的,但是当我试图更深入时,我无法以一致、可重复的方式使事情顺利进行。我向 lodash 寻求帮助,它嘲笑我。我什至尝试创建两个包含我需要的部分的对象,然后将它们合并在一起(a la this)。没有骰子。

所以,我现在转向你,亲爱的读者。

当然,一个完整的解决方案会很棒。但我也很乐意提供链接、建议、警告、观察等。欢迎提供任何帮助。

谢谢!


更新

谢谢你的帮助,阿米尔!

您在上面提供的内容看起来很有希望。它还没有完全实现,但我认为这是朝着正确方向迈出的一步。

这是我从你的代码中得到的:

[
  {
    collectionKey: 'pink',
    collectionEntries: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object]
    ]
  },
...
]

我应该注意,collectionKey该系列中的每一个都是'pink'.

查找对象数组的数组。唔。

我还应该注意,我将您的代码从

let token: {};

let token = {};

知道上面出了什么问题吗?

再次感谢!


更新#2

Amir,您要求查看我正在使用的数据的结构。我通过colors直接导入文件来简化事情(我希望),而不是整个顺风配置。

这里是:

module.exports = {
  black: '#000',
  white: '#fff',
  rose: {
    50: '#fff1f2',
    100: '#ffe4e6',
    200: '#fecdd3',
    300: '#fda4af',
    400: '#fb7185',
    500: '#f43f5e',
    600: '#e11d48',
    700: '#be123c',
    800: '#9f1239',
    900: '#881337',
  },
  pink: {
    50: '#fdf2f8',
    100: '#fce7f3',
    200: '#fbcfe8',
    300: '#f9a8d4',
    400: '#f472b6',
    500: '#ec4899',
    600: '#db2777',
    700: '#be185d',
    800: '#9d174d',
    900: '#831843',
  },

  ...

};

请注意,某些条目不是嵌套的(例如blackand white),但其余条目是嵌套的。

能够适应这种差异会很棒。尝试.push在语句中包装两种不同的方法if,但似乎当我修复一个用例时,我打破了另一个。

再次感谢你的帮助!

标签: javascriptobjectrecursion

解决方案


你可以做这样的事情:

const tailwindSrc = require("../node_modules/tailwindcss/defaultConfig.js");
const colors = tailwindSrc.theme.colors;

const iterateObject = function (object) {
  let tokenList = [];
  let token = {}
  Object.keys(object).forEach((key) => {
    token['collectionKey']= key,
    token['collectionEntries'] = []
    Object.keys(object[key]).forEach((subkey) => {
      token.collectionEntries.push({
        key: subkey,
        value: object[key][subkey],
      });
    });
    tokenList.push({token : token});
  });
  return tokenList;
};

iterateObject(colors);

但这里的结果将是:

{
  token: { 
      collectionKey: 'gray',
      collectionEntries: [
          { key: '100', value: '#f3f4f6' }
          { key: '200', value: '#e5e7eb' }
          { key: '300', value: '#d1d5db' }
          { key: '400', value: '#9ca3af' }
          { key: '500', value: '#6b7280' }
          { key: '600', value: '#4b5563' }
          { key: '700', value: '#374151' }
          { key: '800', value: '#1f2937' }
          { key: '900', value: '#111827' }
      ]
  }
}

所以你可以避免重复键:'item'


推荐阅读