文字列を指定した文字数ごとに分割する

今日は Windows マシンから更新。

 cf. ruby 文字列を指定数で分割する – それマグで!

Haskell でやってみた。

module Main where

slices :: Int -> [a] -> [[a]]
slices _ [] = []
slices n xs = h : slices n d
  where
    (h, d) = splitAt n xs

main :: IO ()
main = print $ slices 3 "abcdefghijklmnopqrstuvwxyz"
^o^ > runhaskell stringSlices.hs
["abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"]

Scheme だとこう。

(define slices
  (lambda (lis n)
    (if (< (length lis) n)
      (list lis)
      (cons (take lis n) (slices (drop lis n) n)))))

(define string-slices
  (lambda (str n)
    (map list->string (slices (string->list str) n))))

(print (string-slices "abcdefghijklmnopqrstuvwxyz" 3))
^o^ > gosh string-slices.scm
(abc def ghi jkl mno pqr stu vwx yz)

最後に JavaScript。

function stringSlices(n, str) {
  var l = str.length;
  var result = [];
  for (var i = 0; i < l; i += n) {
    result.push(str.slice(i, i + n));
  }
  return result;
}

console.log(stringSlices(3, "abcdefghijklmnopqrstuvwxyz"));
^o^ > node stringSlices.js
[ 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz' ]

これ、もうちょっとスマートにいかないかな。

[追記]

JavaScript 版、Haskell 版や Scheme 版と同じように考えてみた。少しはスマートになったかな。そうでもないか?

function stringSlices(n, str) {
  if (str.length == 0) {
    return [];
  } else {
    var l = stringSlices(n, str.slice(n))
    l.unshift(str.slice(0, n))
    return l
  }
}

console.log(stringSlices(3, "abcdefghijklmnopqrstuvwxyz"));
^o^ > node stringSlices2.js
[ 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz' ]