0

I have a quick question. I am fairly new to golang. Say I have a map like so:

map[int]string

How could I randomly split it into two maps or arrays and as close to even as possible? So for example, if there are 15 items, it would be split 7 - 8.

Zoyd
  • 3,449
  • 1
  • 18
  • 27
Alex Kirwan
  • 45
  • 1
  • 8

2 Answers2

2

For example:

func split(m map[int]string) (odds map[int]string, evens map[int]string) {
    n := 1
    odds = make(map[int]string)
    evens = make(map[int]string)
    for key, value := range m {
        if n % 2 == 0 {
            evens[key] = value
        } else {
            odds[key] = value
        }
        n++
    }
    return odds, evens
}

It is actually an interesting example, because it shows a few aspects of Go that are not obvious for beginners:

  • range m iterates in a random order, unlike in any other language as far as I know,
  • the modulo operator % returns the remainder of the integer division,
  • a function can return several values.
Zoyd
  • 3,449
  • 1
  • 18
  • 27
  • 1
    FYI, the "random" iteration order for maps is far from a normal distribution, see http://stackoverflow.com/a/41020528/32880 – JimB Mar 23 '17 at 15:33
2

You could do something like this:

myStrings := make(map[int]string)
// Values are added to myStrings
myStrings2 := make(map[int]string)
// Seed system time for random numbers
rand.Seed(time.Now().UTC().UnixNano())
for k, v := range myStrings {
    if rand.Float32() < 0.5 {
        myStrings2[k] = v
        delete(myStrings, k)

    }
}

https://play.golang.org/p/6OnH1k4FMu

apxp
  • 5,240
  • 4
  • 23
  • 43
  • This does not guarantee an even split, it only splits evenly on average. A 2-4 split happens quite often, roughly 2 times out of 10, and even a 0-6 distribution is possible, though unlikely. – Zoyd Mar 23 '17 at 14:59