首页 > 解决方案 > 点符号对象到多维对象

问题描述

具有以下数据格式:

const flat = {
    '100': 'L1',
    '100.200': 'L1, J2',
    '100.200.300': 'L1, J2, A3',
    '100.200.400': 'L1, J2, A4',
    '100.300': 'L1, J3',
    '100.400.500': 'L1, J4, A5'
};

我想把它改成这样:

{
    "100":{
        "name":"L1",
        "children":{
            "200":{
                "name":"L1, J2",
                "children":{
                    "300":{
                        "name":"L1, J2, A3"
                    },
                    "400":{
                        "name":"L1, J2, A4"
                    }
                }
            },
            "300":{
                "name":"L1, J3"
            },
            "400":{
                "name":null,
                "children":{
                    "500":{
                        "name":"L1, J4, A5"
                    }
                }
            }
        }
    }
}

我一直在尝试从这篇 Stack Overflow 帖子中实现一些东西,尽管它们只涵盖了我的很多用例,而且很难弄清楚。

标签: javascript

解决方案


这是一个使用对提供的对象的Array.prototype.reduce()调用的示例。Object.entries()

function expand(obj) {
  return Object
    .entries(obj)
    .reduce((a, [propString, name]) => {
      const
        propArr = propString.split('.'),
        innerProp = propArr.pop(),
        innerObj = propArr.reduce((_a, prop) => (
          _a[prop] ??= {}, _a[prop]), a);

      innerObj[innerProp] = { name };

      return a;
    }, {})
}

const flat = { '100': 'L1', '100.200': 'L1, J2', '100.200.300': 'L1, J2, A3', '100.200.400': 'L1, J2, A4', '100.300': 'L1, J3', '100.400.500': 'L1, J4, A5' };

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

但是您链接的问题Convert javascript dot notation object to nested object,如果您进行一次更改以适应输入的形状,就可以正常工作。

target[parts[0]] = obj[objectPath]

变成

target[parts[0]] = { name: obj[objectPath] }

// https://stackoverflow.com/questions/7793811/convert-javascript-dot-notation-object-to-nested-object

function deepen(obj) {
  const result = {};

  // For each object path (property key) in the object
  for (const objectPath in obj) {
    // Split path into component parts
    const parts = objectPath.split('.');

    // Create sub-objects along path as needed
    let target = result;
    while (parts.length > 1) {
      const part = parts.shift();
      target = target[part] = target[part] || {};
    }

    // Set value at end of path
    target[parts[0]] = { name: obj[objectPath] }
  }

  return result;
}


const flat = { '100': 'L1', '100.200': 'L1, J2', '100.200.300': 'L1, J2, A3', '100.200.400': 'L1, J2, A4', '100.300': 'L1, J3', '100.400.500': 'L1, J4, A5' };

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


推荐阅读