How to generate a sequence of numbers
Asked Answered
M

5

49

I want to generate a sequence of numbers in Go but I can't find any built-in functions for this.
Basically I want the equivalent of PHP's range function in Golang:

array range ( mixed $start , mixed $end [, number $step = 1 ] )

It would be useful when creating a slice/array of numeric types and you want to populate/initialize it with a numeric sequence.

Monazite answered 5/10, 2016 at 7:37 Comment(0)
D
76

There is no equivalent to PHP's range in the Go standard library. You have to create one yourself. The simplest is to use a for loop:

func makeRange(min, max int) []int {
    a := make([]int, max-min+1)
    for i := range a {
        a[i] = min + i
    }
    return a
}

Using it:

a := makeRange(10, 20)
fmt.Println(a)

Output (try it on the Go Playground):

[10 11 12 13 14 15 16 17 18 19 20]

Also note that if the range is small, you can use a composite literal:

a := []int{1, 2, 3}
fmt.Println(a) // Output is [1 2 3]
Drinkable answered 5/10, 2016 at 7:50 Comment(0)
R
10

1- You may use:

//Create a slice containing a range of elements.
//
//  start: First value of the sequence.
//  end:   The sequence is ended upon reaching the end value.
//  step:  step will be used as the increment between elements in the sequence.
//         step should be given as a positive number.
//
//Return Values: Returns a slice of elements from start to end, inclusive.
func NewSlice(start, end, step int) []int {
    if step <= 0 || end < start {
        return []int{}
    }
    s := make([]int, 0, 1+(end-start)/step)
    for start <= end {
        s = append(s, start)
        start += step
    }
    return s
}

Try it on The Go Playground:

package main

import "fmt"

//Create a slice containing a range of elements.
//
//  start: First value of the sequence.
//  end:   The sequence is ended upon reaching the end value.
//  step:  step will be used as the increment between elements in the sequence.
//         step should be given as a positive number.
//
//Return Values: Returns a slice of elements from start to end, inclusive.
func NewSlice(start, end, step int) []int {
    if step <= 0 || end < start {
        return []int{}
    }
    s := make([]int, 0, 1+(end-start)/step)
    for start <= end {
        s = append(s, start)
        start += step
    }
    return s
}

func main() {
    s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    fmt.Println(s) // [0 1 2 3 4 5 6 7 8 9]

    fmt.Println(NewSlice(10, 19, 1))  // [10 11 12 13 14 15 16 17 18 19]
    fmt.Println(NewSlice(10, 28, 2))  // [10 12 14 16 18 20 22 24 26 28]
    fmt.Println(NewSlice(-10, -1, 1)) // [-10 -9 -8 -7 -6 -5 -4 -3 -2 -1]
}

2- You may use:

// Returns a slice of elements with exact count.
// step will be used as the increment between elements in the sequence.
// step should be given as a positive, negative or zero number.
func NewSlice(start, count, step int) []int {
    s := make([]int, count)
    for i := range s {
        s[i] = start
        start += step
    }
    return s
}

Try it on The Go Playground:

package main

import "fmt"

func NewSlice(start, count, step int) []int {
    s := make([]int, count)
    for i := range s {
        s[i] = start
        start += step
    }
    return s
}

func main() {
    s := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    fmt.Println(s) // [0 1 2 3 4 5 6 7 8 9]

    fmt.Println(NewSlice(10, 10, 1))  // [10 11 12 13 14 15 16 17 18 19]
    fmt.Println(NewSlice(10, 10, 2))  // [10 12 14 16 18 20 22 24 26 28]
    fmt.Println(NewSlice(-1, 10, -1)) // [-1 -2 -3 -4 -5 -6 -7 -8 -9 -10]
    fmt.Println(NewSlice(20, 10, 0))  // [20 20 20 20 20 20 20 20 20 20]
}
Residual answered 5/10, 2016 at 8:3 Comment(0)
V
3
package main

import "fmt"

func main() {

  var a [11]int
  for i := 1; i < len(a); i++ {
    a[i] = i
  }
  
  fmt.Print(a)
}

You will get:

[0 1 2 3 4 5 6 7 8 9 10]
Vaenfila answered 1/11, 2021 at 13:55 Comment(0)
V
0

You can try this code GenerateSequenceInt, it's like Python's range:

package main

import (
    "fmt"
    "errors"
)

func GenerateSequenceInt(begin, end, step int) (sequence []int){
    if step == 0 {
        panic(errors.New("step must not be zero"))
    }
    count := 0
    if (end > begin && step > 0) || (end < begin && step < 0) {
        count = (end-step-begin)/step + 1
    }

    sequence = make([]int, count)
    for i := 0; i < count; i, begin = i+1, begin+step {
        sequence[i] = begin
    }
    return
}

func main() {
    seq1 := GenerateSequenceInt(-1,11,-3)   
    fmt.Println(seq1)

    seq2 := GenerateSequenceInt(1,-1,3)
    fmt.Println(seq2)

    seq3 := GenerateSequenceInt(1,1,1)
    fmt.Println(seq3)

    seq4 := GenerateSequenceInt(1, 11, 2)
    fmt.Println(seq4)

    seq5 := GenerateSequenceInt(1, -11, -2)
    fmt.Println(seq5)
}
Vernacularism answered 20/1, 2020 at 9:38 Comment(0)
G
0

When you create an array/slice of number in golang, it is automatically populated with 0s. You could use the index instead of the value if you need a 0 based range that increases by 1.

nums := make([]int, 10)
for i := range nums {
    //do something with index
    fmt.Println(i)
}

If you needed a different starting point (not zero) and step (not 1) of the range, you could calculate it in a loop. For example, for a range of 10 numbers starting at 100, increasing by 5

nums := make([]int, 10)
for i := range nums {
    nums[i] = 100 + i*5
}

Wrapping it as a function that returns a slice of numbers

func Range(start int, max int, step int) []int {
    count := (max - start) / step
    nums := make([]int, count)
    for i := range nums {
        nums[i] = start + i*step
    }
    return nums
}

Call it as

nums = Range(-50, 150, 10)
fmt.Println(nums)
Gangrel answered 27/9, 2022 at 2:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.