Kashif Khan
Kashif Khan

Reputation: 117

Loop over a dynamic nested struct in golang

I have created a dynamic struct to unmarshal a JSON. Struct looks like :

type Partition struct {
    DiskName      string      `json:"disk_name"`
    Mountpoint    interface{} `json:"mountpoint,omitempty"`
    Size          string      `json:"size"`
    Fstype        string      `json:"fstype,omitempty"`
    SubPartitions bool        `json:"sub_partitions"`
    Partitions    []Partition `json:"partitions,omitempty"`
}

type NasInfo struct {
    Blockdevices []struct {
        DiskName   string      `json:"disk_name"`
        Mountpoint interface{} `json:"mountpoint,omitempty"`
        Size       string      `json:"size"`
        Fstype     string      `json:"fstype,omitempty"`
        Partitions []Partition `json:"partitions,omitempty"`
    } `json:"blockdevices"`
}

Now there can be many partitions inside block devices, and a partition can have more sub partitions in it. I want to manually assign value to a field in partition struct. How can i do that. How can i iterate over each partition and sub partitions and assign a manual value to it. Is there any way to do this ?

Currently using this :

    totalPartitions := len(diskInfo.Blockdevices[0].Partitions)
    if totalPartitions > 0 {
        for i := 0; i < totalPartitions; i++ {
            if diskInfo.Blockdevices[0].Partitions[i].Partitions != nil {
                diskInfo.Blockdevices[0].Partitions[i].SubPartitions = true
            } else {
                diskInfo.Blockdevices[0].Partitions[i].SubPartitions = false
            }
        }
    }

But it can only handle 1 partition with one sub partition. Is there any way i can iterate over each and assign value to it?

Upvotes: 0

Views: 538

Answers (2)

shezzy7
shezzy7

Reputation: 46

Write a function

func markSubPartition(p *Partition) {
if len(p.Partitions) > 0 {
    p.SubPartitions = true
    for _, part := range p.Partitions {
        markSubPartition(part)
    }
} else {
    p.SubPartitions = false
}}

And loop over blockdevices like this

for _, part := range diskInfo.Blockdevices[0].Partitions {
                markSubPartition(part)}

Also need to alter your struct change partition field to : Partitions []*Partition json:"partitions,omitempty" Hope it helps, Thanks!

Upvotes: 1

LeGEC
LeGEC

Reputation: 51780

Since that SubPartitions flag is coupled with Partitions, one option is to remove the SubPartitions field, and add a method that computes this value :

func (p *Partition) HasSubPartitions() bool {
    // note : to check if a slice is empty or not, it is advised to look at
    // 'len(slice)' rather than nil (it is possible to have a non-nil pointer
    // to a 0 length slice)
    return len(p.Partitions) > 0  
}

Upvotes: 1

Related Questions