Golang分组并在goroutine中按值合并

时间:2019-02-06 11:24:28

标签: go

我是新手,尝试用GO中的相同值填充切片数据。 请参考以下示例

input struct {
  ID string `json:"id"`
  Name string `json:"name"`
  Image string `json:"image"`
}

output struct {
  ID    string `json:"id"`
  Name  string `json:"name"`
  Image []img `json:"image"`
}

img struct {
  Name string `json:"name"`
  Width  int  `json:"width"`
  Height int  `json:"height"`
}

input = [{
        "id": 10,
        "name": "product 10",
        "image": {"name": "https://i.imgur.com/eKSk6Fq.jpg"}
    }, {
        "id": 10,
            "name": "product 10",
            "image": {"name": "https://i.imgur.com/np1wmxw.jpg"}
    }, {
        "id": 11,
            "name": "product 11",
            "image": {"name": "https://i.imgur.com/jlFgGpe.jpg"}
    }, {
        "id": 11,
            "name": "product 11",
            "image": {"name": "https://i.imgur.com/B0D4iRk.jpg"}
    }, {
        "id": 11,
            "name": "product 11",
            "image": {"name": "https://i.imgur.com/4AiXzf8.jpg"}
    }]

// expected output
output = [{
    "id": 10,
    "name": "product 10",
    "image": [{
        "name": "https://i.imgur.com/eKSk6Fq.jpg",
        "width": 900,
        "height": 600
    }, {
        "name": "https://i.imgur.com/np1wmxw.jpg",
        "width": 600,
        "height": 600
    }]
}, {
    "id": 11,
    "name": "product 11",
    "image": [{
        "name": "https://i.imgur.com/jlFgGpe.jpg",
        "width": 639,
        "height": 700
    }, {
        "name": "https://i.imgur.com/B0D4iRk.jpg",
        "width": 1280,
        "height": 960
    }, {
        "name": "https://i.imgur.com/4AiXzf8.jpg",
        "width": 540,
        "height": 405
    }]
}]

我想基于同一inputID分组为一个新的切片, 因此,结果output将是新结构的新切片,而新结构的imageID分组。

  • H̶o̶w̶̶w̶o̶u̶l̶d̶̶I̶̶a̶c̶h̶i̶e̶v̶e̶d̶̶t̶h̶e̶̶̶o̶u̶t̶p̶u̶t̶̶r̶e̶s̶u̶l̶t̶̶u̶s̶i̶n̶g̶̶G̶O̶?更新:从彼得·艾希尔斯海姆(Peter Eichelsheim)得到了答案
  • 此外,如果我必须使用http.get在input中设置图像大小,并想使用goroutine,我将如何获得结果?因为我这里的最后一个代码playground未能实现正确的输出(总是获得最后的输入)

注意:我不知道为什么我不能在操场上得到null,但是在我的笔记本电脑中,结果是:[{“ id”:11,“ name”:“ product 11”,“ image”:[{“名称“:” https://i.imgur.com/B0D4iRk.jpg“,”宽度“:1280,”高度“:960}]}}]

在PHP中,我将执行以下操作以实现预期的output

foreach ($input as $key => $value) {
            if (!isset($output[$value["id"]])) {
                $output[$value["id"]] = [
                    "id" => $value["id"],
                    "name" => $value["name"],
                    "image" => [],
                ];
            }

            $get = getimagesize($value["image"]["name"]);
            if ($get) {
                $width  = isset($get[0]) ? $get[0] : 0;
                $height = isset($get[1]) ? $get[1] : 0;
            }

            $output[$value["id"]]["image"][$key] = [
                "name" => $value["image"]["name"],
                "width" => $width,
                "height" => $height,
            ];

            $output[$value["id"]]["image"] = array_values($output[$value["id"]]["image"]);
}

$output = array_values($output);
$json = json_encode($output, true);

echo $json;

谢谢

2 个答案:

答案 0 :(得分:1)

这里有一些带有示例json输入的示例,使用map [int]输出将图像合并成相同的产品ID。

package main

import (
    "encoding/json"
    "fmt"
    "log"
)

type input struct {
    ID    int `json:"id"`
    Name  string `json:"name"`
    Image img    `json:"image"`
}

type output struct {
    ID    int `json:"id"`
    Name  string `json:"name"`
    Image []img  `json:"image"`
}

type img struct {
    Name string `json:"name"`
}

func main() {

    var jsoninput = []byte(`
    [{
        "id": 10,
        "name": "product 10",
        "image": {"name": "image 10a"}
    }, {
        "id": 10,
            "name": "product 10",
            "image": {"name": "image 10b"}
    }, {
        "id": 11,
            "name": "product 11",
            "image": {"name": "image 11a"}
    }, {
        "id": 11,
            "name": "product 11",
            "image": {"name": "image 11b"}
    }, {
        "id": 11,
            "name": "product 11",
            "image": {"name": "image 11c"}
    }]`)

    var inputs []input

    err := json.Unmarshal(jsoninput, &inputs)
    if err != nil {
        log.Fatalln("could not Unmarshal:", err)
    }

    var outputlist = make(map[int]output)

    for _, inp := range inputs {
        outputlist[inp.ID] = output{inp.ID, inp.Name, append(outputlist[inp.ID].Image, inp.Image)}
    }

    var outputs []output

    for _, outp := range outputlist{
        outputs = append(outputs,outp)
    }

    jsonoutput, err := json.Marshal(outputs)

    fmt.Println(string(jsonoutput))
}

答案 1 :(得分:0)

var inputs []input // assuming the json has been unmarshalled correctly

outs := make(map[int]output)

// this will create a map, keyed by id, values are groups of inputs
for _, input := range inputs {

    out, exists := outs[input.ID]
    if !exists {
        out = output{
            ID: input.ID,
            Name: input.Name,
        }
    }

   out.Image = append(out.Image, img{Name: input.Name})
}

output := make([]output, len(outs))
var idx int
for key, out := range outs {
    output[idx] = out
    idx++
}