このサイトのエントリーを全部取得してリストにして、それをたとえば10エントリーごとに分けてページネーションしたい、のような場合の話。 元のリストから n個ごとに分割したサブリストをつくりたい、というケースは結構ある。
追記 kotlinの場合はこちらを参照。
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]]
できた。
とりあえずは、目的を果たしたので、今日はこれまで。
Node.js でも書いたので、メモしておく。
package.json:
{
"name": "my-sublist",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"underscore": "^1.13.1"
}
}
main.js:
sublist という再帰関数を書いた。
const _ = require('underscore');
const sublist = (accum, list, n)=> {
if( list.length==0 ){
return accum;
} else {
accum.push( _.take(list, n) );
return sublist(accum, _.drop(list, n), n);
}
};
const 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(/ /);
const list2 = sublist([], list, 10);
console.log(list2);
実行する
$ node main.js
[
[
'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' ]
]
まてまて、sublist 関数の最初の引数はかならず [] なのだから、それを省略できるようにしよう。
const _ = require('underscore');
const sublist = (list0, n0)=> {
const recur = (accum, list, n)=> {
if( list.length==0 ){
return accum;
} else {
accum.push( _.take(list, n) );
return recur(accum, _.drop(list, n), n);
}
};
return recur([], list0, n0);
};
const 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(/ /);
const list2 = sublist(list, 10);
console.log(list2);
以上。