Chunk a Collection

I have a collection (a list of states) that I want to chunk into a collection of collections (ex. a slice of slices). The code below accomplishes my goal. Is there an easier way?

// inputs
{{ $list := .Site.Data.states }}
{{ $bucket_count := 5 }}

{{ $bucket_size := math.Ceil (div (len $list) (float $bucket_count)) }}
{{ $buckets := slice slice }}
{{ range seq $bucket_count }}
    {{ $bucket := first $bucket_size (after (mul (sub . 1) $bucket_size) $list) }}
    {{ $buckets = $buckets | append $bucket }}
{{ end }}
{{ $buckets = after 1 $buckets }}

//output
{{ $buckets }}

Ideally I could do something like below. This would give me a slice of five slices. Each subslice containing an equal number of items, except for the last subslice which would contain the remainder.

slice_into $list 5

you could create a partial for reuse

call it like that {{ $result := partial "sliceIt" (slice $list $bucket_count) }}

layouts/partials/sliceIt.html

{{ $list := index . 0 }}
{{ $bucket_count := index . 1 }}

{{ $bucket_size := math.Ceil (div (len $list) (float $bucket_count)) }}
{{ $buckets := slice slice }}
{{ range seq $bucket_count }}
   {{ $bucket := first $bucket_size (after (mul (sub . 1) $bucket_size) $list) }}
   {{ $buckets = $buckets | append $bucket }}
{{ end }}
{{ return after 1 $buckets }}

You may want to check your math for edge cases

  • empty arrays are added if the bucket_count is greater then length of list
  • try it with array size = 4 and bucket count = 3 :wink:
    according to your definition it should give [ [One], [Two], [Three, Four]]
    but the result is [ [One, Two], [Three, Four], []]

@irkode, thank you!

  1. Thanks for sharing how to reuse code with partials!
  2. Thanks for taking the time to read my code and identify an edge case.

Have a great weekend!

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.