【问题标题】:Compose object from nested list从嵌套列表中组合对象
【发布时间】:2022-01-16 21:48:05
【问题描述】:

我有一个从 XML 生成的通用 json。

{
  "contextInfoDTOList": [
    {
      "key": "context_info",
      "list": [
        {
          "key": "composition",
          "list": [
            {
              "key": "parts",
              "list": [
                {
                  "key": "part",
                  "list": [
                    {
                      "list": [
                        {
                          "key": "materials",
                          "list": [
                            {
                              "key": "material",
                              "list": [
                                {
                                  "key": "material_value",
                                  "value": "100"
                                },
                                {
                                  "key": "material_name",
                                  "value": "polyester"
                                }
                              ]
                            }
                          ]
                        },
                        {
                          "key": "part_name",
                          "value": "LINING"
                        }
                      ]
                    },
                    {
                      "list": [
                        {
                          "key": "materials",
                          "list": [
                            {
                              "key": "material",
                              "list": [
                                {
                                  "key": "material_value",
                                  "value": "100"
                                },
                                {
                                  "key": "material_name",
                                  "value": "cow leather"
                                }
                              ]
                            }
                          ]
                        },
                        {
                          "key": "part_name",
                          "value": "OUTER SHELL"
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "key": "explanation"
        }
      ]
    }
  ]
}

我需要将信息提取成这样的:

COMPOSITION

Lining

100 % polyester

Outer Shell

100 % cow leather

我尝试了一种 forEach 方法,加入了键(成分、零件、材料...),但它变得很脏,我无法获得材料列表。

我正在考虑使用reduce来获取对象,但我不知道如何通过嵌套列表传递对象并使用递归。

想要的对象:

export class ContextInfo {
  composition: Composition;
  explanation: string;
}
export class Composition {
  parts: Part[] = [];
}

export class Part {
  partName: string;
  materials: Material[] = [];
}

export class Material {
  name: string;
  value: number;
}

任何帮助将不胜感激。提前致谢!

【问题讨论】:

    标签: javascript typescript recursion


    【解决方案1】:

    现在你有责任处理数据...

    let contextInfoDTOList = [{ key: "context_info", list: [{ key: "composition", list: [{ key: "parts", list: [{ key: "part", list: [{ list: [{ key: "materials", list: [{ key: "material", list: [{ key: "material_value", value: "100" }, { key: "material_name", value: "polyester" }] }] }, { key: "part_name", value: "LINING" }] }, { list: [{ key: "materials", list: [{ key: "material", list: [{ key: "material_value", value: "100" }, { key: "material_name", value: "cow leather" }] }] }, { key: "part_name", value: "OUTER SHELL" }] }] }] }] }, { key: "explanation" }] }]
    function* getAllKeyValue(list = [], path = []) {
        for (let item of list)
            if ("value" in item)
                yield [item, path]
            else
                yield* getAllKeyValue(item.list, path.concat(item.key))
    }
    for (let [item, _path] of getAllKeyValue(contextInfoDTOList)) {
        console.log(item);
        // Todo: work with the data
    }

    【讨论】:

    • 我认为这是查找所有叶键值对的好方法。但是,即使您还匹配到这些节点的路径,我认为它仍然会将大部分工作留在其他地方。换句话说,这是一种很好的方法,但可能对其他问题比对这个问题更有用。 (不过,我很乐意被证明是错误的。)
    【解决方案2】:

    这是一种非常难看的输入格式。但是通过不断过滤和查找节点,我们可以以相当合理的方式构建您的输出:

    const byKey = (target) => ({key}) => key == target
    
    const extract = (res) => res .contextInfoDTOList .filter (byKey ('context_info')) .map (info => ({
      explanation: info .list .find (byKey ('explanation')) .value,
      composition: info .list .find (byKey ('composition')) .list .filter (byKey ('parts')) .map (parts => ({
        parts: parts .list .filter (byKey ('part')) .flatMap (p => p.list .map (q => q.list)) .map (part => ({
          partName: part .find (byKey ('part_name')) .value,
          material: part .find (byKey ('materials')) .list .map (material => ({
            name: material .list .find (byKey ('material_name')) .value,
            value: material .list .find (byKey ('material_value')) .value
          }))
        }))
      }))
    }))
    
    
    const res = {contextInfoDTOList: [{key: "context_info", list: [{key: "composition", list: [{key: "parts", list: [{key: "part", list: [{list: [{key: "materials", list: [{key: "material", list: [{key: "material_value", value: "100"}, {key: "material_name", value: "polyester"}]}]}, {key: "part_name", value: "LINING"}]}, {list: [{key: "materials", list: [{key: "material", list: [{key: "material_value", value: "100"}, {key: "material_name", value: "cow leather"}]}]}, {key: "part_name", value: "OUTER SHELL"}]}]}]}]}, {key: "explanation", value: "foobar"}]}]}
    
    console .log (extract (res))
    .as-console-wrapper {max-height: 100% !important; top: 0}

    (请注意,我必须向您的 "explanation" 节点添加一个虚拟的 "value" 以使其正确提取。如果我们不这样做,我们会得到一个 undefined 的解释。)

    我们使用 helper byKey 只是为了减少函数体中的噪音。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-07
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2017-05-09
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      相关资源
      最近更新 更多