2015年11月13日金曜日

Google Spreadsheet - カスタム関数 FLATTEN, CHUNK, RESHAPE

組込であると便利な配列の変形関数群

FLATTEN

2次元配列を1次元配列に変形

/**
 * 2次元配列を配列を平坦にする
 *
 * @param {Range} range 2-dimensional array
 * @return flatted array
 * @customfunction
 */
function FLATTEN(range) {
  return Array.prototype.concat.apply([], range);
}

CHUNK

1次元配列を n要素の2次元配列へ変形
※ この実装では Math.floorで配列長を決めているため、割り切れない場合の末尾は切り捨て

/**
 * 指定された数の要素毎に配列を分割
 *
 * @param {4} n 分割する要素数
 * @param {A1:A12} xs データ・ソースとなる配列
 * @return n要素毎に分割された2次元配列
 * @customfunction
 */
function CHUNK(n, xs) {
  var length = Math.floor(xs.length/n);
  var result = new Array(length);
  for (var i = 0; i < length; ++i) {
    result[i] = xs.slice(i*n, i*n+n);
  }
  return result;
}

RESHAPE

2次元配列の変形

/*
 * 2次元配列の変形
 *
 * @param {Number} row 変形する行数
 * @param {Number} col 変形する列数
 * @param {Range} range 変換対象とする範囲
 * @return 変形後の行列
 * @customfunction
 */
function RESHAPE(row, col, range) {
  var flatted = FLATTEN(range);
  if (Math.floor(flatted.length/col) != row) { throw new Error("サイズが一致しません"); }
  return CHUNK(col, flatted);
}

4列で折り返し表示のような場合は、CHUNK。空行を挟みたい場合などは縦横を入れ替える組み込み関数のTRANSPOSEで空列を含めて変形する、等。

プリミティブな操作なので応用範囲は広いはず。下図は、1x16 の範囲を 4x4 へ変形した例。

0 件のコメント:

コメントを投稿