1package main
2
3import (
4 "math/rand"
5 "reflect"
6 "time"
7)
8
9// firstN returns the first n items of a slice.
10func firstN(n int, items interface{}) interface{} {
11 v := reflect.ValueOf(items)
12 if v.Kind() != reflect.Slice {
13 panic("firstN: not a slice")
14 }
15 if v.Len() < n {
16 return items
17 }
18 return v.Slice(0, n).Interface()
19}
20
21// lastN returns the last n items of any slice.
22func lastN(n int, items interface{}) interface{} {
23 v := reflect.ValueOf(items)
24 if v.Kind() != reflect.Slice {
25 panic("lastN: not a slice")
26 }
27 l := v.Len()
28 if l < n {
29 return items
30 }
31 return v.Slice(l-n, l).Interface()
32}
33
34// randomN returns n random items of any slice.
35func randomN(n int, items interface{}) interface{} {
36 v := reflect.ValueOf(items)
37 if v.Kind() != reflect.Slice {
38 panic("randomN: not a slice")
39 }
40 l := v.Len()
41 if l < n {
42 return items
43 }
44 rand.Seed(time.Now().UnixNano())
45 indices := rand.Perm(l)[:n]
46 result := reflect.MakeSlice(v.Type(), n, n)
47 for i, idx := range indices {
48 result.Index(i).Set(v.Index(idx))
49 }
50 return result.Interface()
51}
52
53// filterByType filters pages by their type.
54func filterByType(pageType string, pages interface{}) interface{} {
55 v := reflect.ValueOf(pages)
56 if v.Kind() != reflect.Slice {
57 panic("filterByType: not a slice")
58 }
59
60 var filtered []interface{}
61 for i := 0; i < v.Len(); i++ {
62 page := v.Index(i).Interface().(Page)
63 if page.Type == pageType {
64 filtered = append(filtered, page)
65 }
66 }
67 return filtered
68}
69