0

我有一个包含分层数据的数组,我想将其转换为层次结构,但格式不同。我尝试使用递归方法,但它没有提供正确的数据

下面是我试图实现的代码

static convertConfigJson(data, finalResults = []) {

        const configData = JSON.parse(JSON.stringify(data));

        return configData.map((item) => {
            const { name, type, value, path } = item;
            let children = {}
            if (type === 'Object') {
              children = this.convertConfigJson(value, finalResults);
            } else {

            finalResults.push({
                id: name,
                name: name,
                children: children
            })
            }




            console.log('>>>>>>>>>', finalResults)

            return finalResults;
          });   
    }

下面是我从 API 获得的 JSON 数组

[
        {
            "name": "info",
            "type": "Object",
            "value": [
                {
                    "name": "app",
                    "type": "Object",
                    "value": [
                        {
                            "path": "info.app",
                            "name": "encoding",
                            "type": "TEXT",
                            "value": "@project.build.sourceEncoding@"
                        },
                        {
                            "name": "java",
                            "type": "Object",
                            "value": [
                                {
                                    "path": "info.app.java",
                                    "name": "source",
                                    "type": "TEXT",
                                    "value": "@java.version@"
                                },
                                {
                                    "path": "info.app.java",
                                    "name": "target",
                                    "type": "TEXT",
                                    "value": "java.version@"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]

我想将上面的数组转换为以下格式,即将值数组更改为子数组

[
    {
        "name": "info",
        "type": "Object",
        "children": [
            {
                "name": "app",
                "type": "Object",
                "children": [
                    {
                        "path": "info.app",
                        "name": "encoding",
                        "type": "TEXT",
                        "value": "@project.build.sourceEncoding@"
                    },
                    {
                        "name": "java",
                        "type": "Object",
                        "children": [
                            {
                                "path": "info.app.java",
                                "name": "source",
                                "type": "TEXT",
                                "value": "@java.version@"
                            },
                            {
                                "path": "info.app.java",
                                "name": "target",
                                "type": "TEXT",
                                "value": "java.version@"
                            }
                        ]
                    }
                ]
            }
        ]
    }
]
4

4 回答 4

5

对 children 属性中的所有元素进行简单的递归遍历。将 .value 设置为 .children 并删除 .value

walk = node => {
  if(!node.value || typeof node.value!=='object') return
  node.children = node.value
  delete node.value
  node.children.forEach(walk)
}

data.forEach(walk)

console.log(data)
<script>
data=[
        {
            "name": "info",
            "type": "Object",
            "value": [
                {
                    "name": "app",
                    "type": "Object",
                    "value": [
                        {
                            "path": "info.app",
                            "name": "encoding",
                            "type": "TEXT",
                            "value": "@project.build.sourceEncoding@"
                        },
                        {
                            "name": "java",
                            "type": "Object",
                            "value": [
                                {
                                    "path": "info.app.java",
                                    "name": "source",
                                    "type": "TEXT",
                                    "value": "@java.version@"
                                },
                                {
                                    "path": "info.app.java",
                                    "name": "target",
                                    "type": "TEXT",
                                    "value": "java.version@"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
</script>

于 2020-06-11T15:14:39.057 回答
1

writetransform方法,当对象的“值”类型是数组时,transform递归调用。

const transform = ({ value, ...rest }) => {
  const item = { ...rest };
  Array.isArray(value)
    ? (item["children"] = value.map(transform))
    : (item["value"] = value);
  return item;
};

// Update: Based on @user120242 suggestion, creating another object is not required and using `Object.assign` will simplify.

const transform2 = ({ value, ...rest }) =>
  Object.assign(
    rest,
    Array.isArray(value) ? { children: value.map(transform2) } : { value }
  );

const items = [
  {
    name: "info",
    type: "Object",
    value: [
      {
        name: "app",
        type: "Object",
        value: [
          {
            path: "info.app",
            name: "encoding",
            type: "TEXT",
            value: "@project.build.sourceEncoding@",
          },
          {
            name: "java",
            type: "Object",
            value: [
              {
                path: "info.app.java",
                name: "source",
                type: "TEXT",
                value: "@java.version@",
              },
              {
                path: "info.app.java",
                name: "target",
                type: "TEXT",
                value: "java.version@",
              },
            ],
          },
        ],
      },
    ],
  },
];

const output = items.map(transform);
console.log(output);

console.log(items.map(transform2));

于 2020-06-11T16:37:03.940 回答
1

此技术类似于 user120242 的答案,但它不会改变您的输入结构,而是创建一个新结构:

const transform = ({value, ...rest}) => 
  Array .isArray (value)
    ? {...rest, children: value .map (transform)}
    : {...rest, value}

const data = [{name: "info", type: "Object", value: [{name: "app", type: "Object", value: [{path: "info.app", name: "encoding", type: "TEXT", value: "@project.build.sourceEncoding@"}, {name: "java", type: "Object", value: [{path: "info.app.java", name: "source", type: "TEXT", value: "@java.version@"}, {path: "info.app.java", name: "target", type: "TEXT", value: "java.version@"}]}]}]}]

console .log (data .map (transform))

更新

借用sivako的技术,我们可以很好地简化它:

const transform = ({value, ...rest}) => ({
  ... rest, 
  ... (Array .isArray (value) ? {children: value .map (transform)} : {value})
})

const data = [{name: "info", type: "Object", value: [{name: "app", type: "Object", value: [{path: "info.app", name: "encoding", type: "TEXT", value: "@project.build.sourceEncoding@"}, {name: "java", type: "Object", value: [{path: "info.app.java", name: "source", type: "TEXT", value: "@java.version@"}, {path: "info.app.java", name: "target", type: "TEXT", value: "java.version@"}]}]}]}]

console .log (data .map (transform))

于 2020-06-11T15:27:44.263 回答
0

"value": [一个最简单的方法是在"children": [stringify 之后替换所有

function convertConfigJson(data) {
  const configData = JSON.parse(JSON.stringify(data).replace(/"value":\[/g, '"children":['));
  return configData
}

您也可以一一遍历嵌套对象的所有键,并将值键替换为值中的数组给孩子

于 2020-06-11T15:18:09.850 回答