Extending an array to a specified length, alternating directions I am working on golang and trying to understand to write good code not translated from another language, so I have written this program just for learning.

I want to perform operation on this array [1,2,3,4] with limit of 10, so that i get this output [1,2,3,4, 4,3,2,1, 1,2].

This function working correctly but I want to see suggestions for optimizations and improvements.

package main

import "fmt"

func arrayExm(array []int, limit int) []int {
    var res []int

    length := len(array)

    for i:=0; i &lt; limit; i++ {

        if(i/length)%2 == 0{
            res = append(res,array[i%length])

        } else {
            res = append(res, array[length -i % length - 1])
        }
    }

    return res

}
func main() {
 fmt.Println(" Array with limit", arrayExm([]int{1,2,3,4},10))
}
This function working correctly but I want to see suggestions for
  optimizations and improvements.


Your source code is undocumented. See Godoc: documenting Go code.

By design, Go has a short, readable specification: The Go Programming Language Specification. As you write code, read useful parts of it in detail, for exanple, make (to make precise allocations), append (which may require multiple reallocations), copy (which has minimal bounds checking and may do block copies), and Index Expressions (which often require a bounds check), and so on.

Browse the Go standard library for useful packages. For example, the testing package provides testing and benchmark facilities.

Read and apply the Go Code Review Comments.

Your algorithm takes an array element view of the problem. Consider other algorihms. For example, a repeating, alternating pattern of input and reverse input.




  I want to see other way.


That's an excellent idea. I usually try to come up with three different ways to do things, although I often settle for two. I use code reviews to ask other people for ideas.

Here's one other way. It's a little different and much more efficient than your way. It uses the Go standard library and code review conventions, and Go's test and benchmark facilities.

alternate.go:

package main

import "fmt"

// alternate returns a list of length n
// with alternating a and reverse a.
func alternate(a []int, n int) []int {
    b := make([]int, n)
    // copy a
    copy(b, a)
    // copy reverse a
    for i, j := len(a)-1, len(a); i &gt;= 0 &amp;&amp; j &lt; len(b); i, j = i-1, j+1 {
        b[j] = a[i]
    }
    // copy repeating pattern
    for i := 2 * len(a); i &lt; n; i *= 2 {
        copy(b[i:], b[:i])
    }
    return b
}

func main() {
    a := []int{1, 2, 3, 4}
    for i := 0; i &lt; 4*len(a)+2; i++ {
        fmt.Println(alternate(a, i), i)
    }
}


Output:

$ go run alternate.go
[] 0
[1] 1
[1 2] 2
[1 2 3] 3
[1 2 3 4] 4
[1 2 3 4 4] 5
[1 2 3 4 4 3] 6
[1 2 3 4 4 3 2] 7
[1 2 3 4 4 3 2 1] 8
[1 2 3 4 4 3 2 1 1] 9
[1 2 3 4 4 3 2 1 1 2] 10
[1 2 3 4 4 3 2 1 1 2 3] 11
[1 2 3 4 4 3 2 1 1 2 3 4] 12
[1 2 3 4 4 3 2 1 1 2 3 4 4] 13
[1 2 3 4 4 3 2 1 1 2 3 4 4 3] 14
[1 2 3 4 4 3 2 1 1 2 3 4 4 3 2] 15
[1 2 3 4 4 3 2 1 1 2 3 4 4 3 2 1] 16
[1 2 3 4 4 3 2 1 1 2 3 4 4 3 2 1 1] 17
$ 


alternate_test.go:

package main

import (
    "fmt"
    "testing"
)

func TestAlternate(t *testing.T) {
    a := []int{1, 2, 3, 4}
    n := 10
    got := fmt.Sprint(alternate(a, n))
    want := fmt.Sprint([]int{1, 2, 3, 4, 4, 3, 2, 1, 1, 2})
    if want != got {
        t.Errorf("want: %v got: %v", want, got)
    }
}

func BenchmarkAlternate(b *testing.B) {
    a := make([]int, 42)
    for i := range a {
        a[i] = i
    }
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i &lt; b.N; i++ {
        alternate(a, 1024)
    }
}

func arrayExm(array []int, limit int) []int {
    var res []int
    length := len(array)
    for i := 0; i &lt; limit; i++ {
        if (i/length)%2 == 0 {
            res = append(res, array[i%length])
        } else {
            res = append(res, array[length-i%length-1])
        }
    }
    return res
}

func BenchmarkArrayExm(b *testing.B) {
    a := make([]int, 42)
    for i := range a {
        a[i] = i
    }
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i &lt; b.N; i++ {
        arrayExm(a, 1024)
    }
}


Output:

$ go test -v -bench=. alternate.go alternate_test.go
=== RUN   TestAlternate
--- PASS: TestAlternate (0.00s)
goos: linux
goarch: amd64
BenchmarkAlternate-4    500000    2576 ns/op    8192 B/op    1 allocs/op
BenchmarkArrayExm-4      50000   25783 ns/op   16376 B/op   11 allocs/op
PASS
ok      command-line-arguments  4.388s
$