go – Paginating a slice-ThrowExceptions

Exception or error:

What’s the best way to paginate over a slice in Go and avoid errors like panic: runtime error: slice bounds out of range

For example, if I have a slice like

slice := []int{1, 2, 3, 4, 5, 6, 7}

and I call

slice[6:10]

I get a panic error.

I came up with this:

func paginate(x []int, skip int, size int) []int {
  limit := func() int {
    if skip+size > len(x) {
      return len(x)
    } else {
      return skip + size
    }

  }

  start := func() int {
    if skip > len(x) {
      return len(x)
    } else {
      return skip
    }

  }
  return x[start():limit()]
}

link to playground

Are there better ways to do this in Go?

Thanks

How to solve:

Well, while there is no nice way to do it, I think it would be cleaner if you used variables instead of functions. It also looks cleaner when you remove the else clause.

func paginate(x []int, skip int, size int) []int {
    if skip > len(x) {
        skip = len(x)
    }

    end := skip + size
    if end > len(x) {
        end = len(x)
    }

    return x[skip:end]
}

Answer:

Why limit to a certain slice type?

func Paginate(pageNum int, pageSize int, sliceLength int) (int, int) {
    start := pageNum * pageSize

    if start > sliceLength {
        start = sliceLength
    }

    end := start + pageSize
    if end > sliceLength {
        end = sliceLength
    }

    return start, end
}
    start, end := Paginate(pageNum, pageSize, len(someSlice))
    pagedSlice := someSlice[start:end]

Answer:

I just found go-linq, which is inspired by Microsoft Linq

To paginate, like in the question I posted, you would write:

From(x).Skip(0).Take(10)

And you will get the expected result. This library takes care of returning an empty slice if your Skip and/or Take values would otherwise result in an out of range error.

Leave a Reply

Your email address will not be published. Required fields are marked *