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?
CodePudding user response:
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.