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