嵌套对象的迭代访问

时间:2018-12-18 01:23:50

标签: python django recursion

问题描述

问题是经典的物料清单(BoM)问题; 假设我们将类BomEntry(object)定义为:

class BomEntry:
    def __init__(self, part, quantity=0, unit="", children=[]):
        self.part = part
        self.quantity = quantity
        self.unit = unit
        self.children = children

part是Django模型,quantityunit是其两个成员。

Django模型具有方法make_bom(self),该方法返回BomEntry(不使用django的类)的实例。 Asm是跟踪数据库中BoM数据的django模型

def make_bom(self, depth=1):
    if not self.is_asm:
        return BomEntry(self, 1, "", [])
    else:
        children = list(Asm.objects.filter(parent=self))
        children_bom = [BomEntry(obj.child, obj.quantity, obj.unit, []) for obj in children]
        bom = BomEntry(self, 1, "", children=children_bom)
        return bom

我目前正在包含一个参数来确定BoM的深度,但是我无法确定如何使用它。

我希望能够遍历嵌套对象,最终得到类似于以下内容的输出:

{
    'part': <PartAsm: 100-1822-R1-A>,
    'quantity': 1,
    'unit': '',
    'children':
        [
            {
                'part': <PartAsm: 100-1823-R1-A>, 
                'quantity': 1,
                'unit': '', 
                'children': 
                    []
            },
            {
                'part':
                <PartAsm: 100-1824-R1-A>, 
                'quantity': 1,
                'unit': '', 
                'children': 
                [
                    {
                        'part': <PartAsm: 100-1825-R1-A>, 
                        'quantity': Decimal('1.00'), 
                        'unit': 'g', 
                        'children': 
                        []
                    },
                    {
                        'part': <PartAsm: 100-1826-R1-A>, 
                        'quantity': Decimal('1.00'), 
                        'unit': 'g', 
                        'children': 
                        []
                    }
                ]
            }
        ]
}

上面的输出是使用控制台获得的,对于循环或递归的任何建议,我将不胜感激。希望我提供了足够清晰的信息

2 个答案:

答案 0 :(得分:1)

ngOnInit() { this.eventsList = [ ['item 1 A','item 2 A'], ['item 1 B','item 2 B'], ['item 1 C','item 2 C'] ]; this.events = [].concat.apply([], this.eventsList); this.form = new FormGroup({ type: new FormControl(), state: new FormControl(), events: this.buildEventsForm() }); } buildEventsForm() { let formControlArr = this.events.map((e: any) => { return new FormControl(false); }); return new FormArray(formControlArr); } 大于depth时,1应该递归,使通话中的make_bom()递减。

depth

答案 1 :(得分:0)

我终于使用@Barmar的宝贵输入使它工作了。 MessageReceivedAsync函数现在看起来像:

LuisDialog

我添加了make_bomdef make_bom(self, quantity=1, unit="def_unit", depth=1): if not self.is_asm: return BomEntry(self, quantity, unit, []) else: if depth <= 1: children = list(Asm.objects.filter(parent=self)) children_bom = [BomEntry(obj.child, quantity*obj.quantity, obj.unit, []) for obj in children] bom = BomEntry(self, quantity, unit, children=children_bom) else: bom = BomEntry(self, quantity, "def_unit", children=[a.child.make_bom(quantity*a.quantity, a.unit, depth - 1) for a in list(Asm.objects.filter(parent=self))]) return bom 参数以求完整性。

感谢一百万@Barmar