Home About
Golang , Groovy

Golang, リストを n 個ごとに分割してサブリストをつくりたい

このサイトのエントリーを全部取得してリストにして、それをたとえば10エントリーごとに分けてページネーションしたい、のような場合の話。 元のリストから n個ごとに分割したサブリストをつくりたい、というケースは結構ある。

例によって groovy で表現すればどうなるかを書く。

main.groovy

def list = "a b c d e f g h i j k l m n o p q r s t u v w x y z".split(/ /)

int columnCount = 10
def rowList = []
while( list.size()>0 ){
    def cellList = list.take(columnCount)
    rowList << cellList
    list = list.drop(columnCount)
}
println rowList

この take, drop を使うことで簡単にサブリストをつくることができる。 (たぶん、もっと良い方法があるとは思うけど)

実行すると、以下のようになる。

$ groovy main
[[a, b, c, d, e, f, g, h, i, j], [k, l, m, n, o, p, q, r, s, t], [u, v, w, x, y, z]]

これをそのまま Golang で表現しようと思ったが、まだ Golang 力が足りない。 取り急ぎ、for ループで地道に実装した。

main.go

package main

import (
	"fmt"
	"strings"
)

func main() {
	list := strings.Split("a b c d e f g h i j k l m n o p q r s t u v w x y z", " ")

	columnCount := 10
	rowCount := (len(list) / columnCount) + 1

	rowList := [][]string{}
	for rowIndex := 0; rowIndex < rowCount; rowIndex++ {
		cellList := []string{}
		for columnIndex := 0; columnIndex < columnCount; columnIndex++ {
			index := rowIndex*columnCount + columnIndex
			if index < len(list) {
				cellList = append(cellList, list[index])
			}
		}

		if len(cellList) > 0 {
			rowList = append(rowList, cellList)
		}
	}

	fmt.Println(rowList)
}

変数名の rowList や cellList はテーブル(またはスプレッドシート)をイメージした変数名です。 リストを n 個に分割するとき、 n 列 x (len(リスト)/n+1)行 のテーブルに変形することを頭の中で想像する。

実行する。

$ go run main.go
[[a b c d e f g h i j] [k l m n o p q r s t] [u v w x y z]]

できた。

とりあえずは、目的を果たしたので、今日はこれまで。