Parse multidimensional arrays in GO

Issue

I wold like to parse a multidimensional array in GO

The goal is to unserialize a array string a run into a loop to get the values.

In PHP, i use this:

Code:

<?php
$x='a:2:{i:0;a:6:{s:8:"category";i:0;s:3:"url";s:0:"";s:6:"ruleid";i:0;s:9:"redirtype";i:0;s:8:"protocol";i:0;s:6:"PARSED";a:1:{s:4:"path";s:0:"";}}i:1;a:6:{s:8:"category";i:0;s:3:"url";s:3:"jjj";s:6:"ruleid";i:0;s:9:"redirtype";i:0;s:8:"protocol";i:0;s:6:"PARSED";a:1:{s:4:"path";s:3:"jjj";}}}';
$x = unserialize($x);
//Print Array
print_r($x);
//Parse Array
foreach ($x as $key => $value){
    //commandes
    echo "category is :".$x[$key]["category"]."\n";
    
    echo "path is :".$x[$key]["PARSED"]["path"]."\n";
}

Output:

Array
(
    [0] => Array
        (
            [category] => 0
            [url] => 
            [ruleid] => 0
            [redirtype] => 0
            [protocol] => 0
            [PARSED] => Array
                (
                    [path] => 
                )

        )

    [1] => Array
        (
            [category] => 0
            [url] => jjj
            [ruleid] => 0
            [redirtype] => 0
            [protocol] => 0
            [PARSED] => Array
                (
                    [path] => jjj
                )

        )

)
category is :0
path is :
category is :0
path is :jjj

In GO, i manage to unserialize the string but i don’t know how to run the loop like in php

Code:

package main

import (
    "fmt"
    "github.com/techoner/gophp/serialize"
)

func main() {
    var line = []byte(`a:2:{i:0;a:6:{s:8:"category";i:0;s:3:"url";s:0:"";s:6:"ruleid";i:0;s:9:"redirtype";i:0;s:8:"protocol";i:0;s:6:"PARSED";a:1:{s:4:"path";s:0:"";}}i:1;a:6:{s:8:"category";i:0;s:3:"url";s:3:"jjj";s:6:"ruleid";i:0;s:9:"redirtype";i:0;s:8:"protocol";i:0;s:6:"PARSED";a:1:{s:4:"path";s:3:"jjj";}}}`)
    out, _ := serialize.UnMarshal([]byte(line))
    fmt.Println(out)
}

Output:

[map[PARSED:map[path:<nil>] category:0 protocol:0 redirtype:0 ruleid:0 url:<nil>] 

map[PARSED:map[path:jjj] category:0 protocol:0 redirtype:0 ruleid:0 url:jjj]]

Anyone can help?

Solution

In Golang you haven’t any parser for unknown arrays or objects, your unknown data is the interface so first, you should cast the data to an array or object and then loop through it, the below code will do what you want.

func main() {
    var line = []byte(`a:2:{i:0;a:6:{s:8:"category";i:0;s:3:"url";s:0:"";s:6:"ruleid";i:0;s:9:"redirtype";i:0;s:8:"protocol";i:0;s:6:"PARSED";a:1:{s:4:"path";s:0:"";}}i:1;a:6:{s:8:"category";i:0;s:3:"url";s:3:"jjj";s:6:"ruleid";i:0;s:9:"redirtype";i:0;s:8:"protocol";i:0;s:6:"PARSED";a:1:{s:4:"path";s:3:"jjj";}}}`)

    out, _ := serialize.UnMarshal(line)
    dataList := out.([]interface{})
    for _, data := range dataList {
        for k, v := range data.(map[string]interface{}) {
            if k == "category" {
                fmt.Printf("category is :%v\n", v)
            } else if k == "PARSED" {
                fmt.Printf("path is :%v\n", v.(map[string]interface{})["path"])
            }
        }
    }
}

output:

path is :<nil>
category is :0
category is :0
path is :jjj

also, this package hasn’t any casting method like json.Unmarshal so you should do it with your own knowledge of your data.

Answered By – ttrasn

Answer Checked By – Marie Seifert (GoLangFix Admin)

Leave a Reply

Your email address will not be published.