9

I'm trying to merge the array values of multiple arrays with same keys (sort of group by + merge). Is there any native way in Go to transform this input:

input = [
    [
        { a: 1, b: [1,2]},
        { a: 2, b: [1,2]},
        { a: 3, b: [1,2]}
    ],
    [
        { a: 1, b: [3,4]},
        { a: 2, b: [3,4]},
        { a: 3, b: [3,4]},
        { a: 4, b: [3,4]}
    ],
    [
        { a:1, b: [5,6]},
        { a:2, b: [5,6]},
        { a:3, b: [5,6]},
        { a:4, b: [5,6]},
        { a:5, b: [5,6]}
    ]
 ]

into:

output = [
    { a: 1, b: [1,2,3,4,5,6]},
    { a: 2, b: [1,2,3,4,5,6]},
    { a: 3, b: [1,2,3,4,5,6]},
    { a: 4, b: [3,4, 5,6]},
    { a: 5, b: [5,6]},
]
Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
inalgnu
  • 123
  • 1
  • 1
  • 6
  • I don't get the logic behind this? Do you calculate `a` value from the count of `b` indexes? – IvRRimUm Oct 15 '16 at 22:30
  • nope, i trying to merge all "b" values of the same "a" value. so for a : 1 => [1,2] + [3,4] + [5,6] (b values from all the other arrays with the same "a" value) – inalgnu Oct 15 '16 at 22:36
  • See this related question: [Group and sum slice of structs](http://stackoverflow.com/questions/39987023/golang-group-and-sum-slice-of-structs/39989962#39989962). – icza Oct 16 '16 at 05:13

1 Answers1

22

Your code isn't Go code (it would pass as Ruby), which, along with no clear attempt on your part to actually solve the problem, is probably why you got some downvotes and no answers yet.

One approach would be to interpret your code as Ruby would, with input a slice of slices of maps of (string, maybe, although Ruby would treat them as Symbols) keys to either ints (in the case of a) or slices of ints (in the case of b). You could do that with the map values using the empty interface (interface{}), but it would be more straightforward to use a struct like this:

type ab struct {
    a int
    b []int
}

and have input be a [][]ab. But as long as we're restructuring your data to fit the language better, it's even more straightforward to do away with a and b altogether, replacing that structure with a map where the a values are the keys and the b values are the values. Things are then a simple matter of iterating over input and appending slices into output:

package main

import "fmt"

func main() {
    input := []map[int][]int{
        {
            1: []int{1, 2},
            2: []int{1, 2},
            3: []int{1, 2},
        },
        {
            1: []int{3, 4},
            2: []int{3, 4},
            3: []int{3, 4},
            4: []int{3, 4},
        },
        {
            1: []int{5, 6},
            2: []int{5, 6},
            3: []int{5, 6},
            4: []int{5, 6},
            5: []int{5, 6},
        },
    }

    output := make(map[int][]int)

    for _, m := range input {
        for k, v := range m {
            output[k] = append(output[k], v...)
        }
    }

    fmt.Println(output)
}

This produces the output:

map[1:[1 2 3 4 5 6] 2:[1 2 3 4 5 6] 3:[1 2 3 4 5 6] 4:[3 4 5 6] 5:[5 6]]

output thus has the data organized as you wanted, given the modified way of representing that data organization.

Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
  • thank you @darshan-rivka-whittle for your response. Sorry my question was not clear enough, i was thinking about a json array input and a json array output. – inalgnu Nov 15 '16 at 21:01
  • What if a is actually an object of int and string , not just an int? – DoIt Apr 06 '20 at 16:05