从嵌套列表中组合对象

Posted

技术标签:

【中文标题】从嵌套列表中组合对象【英文标题】: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;

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

【问题讨论】:

【参考方案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 只是为了减少函数体中的噪音。

【讨论】:

以上是关于从嵌套列表中组合对象的主要内容,如果未能解决你的问题,请参考以下文章

Python中嵌套列表中的列表组合

如何将列表中的元素组合到新的嵌套列表中?

如何从对象列表中填充组合框

获取嵌套字典与列表的组合数

求大神支招,python循环打印两个嵌套列表组合

如何从所有蛮力组合中找到最佳解决方案?