1. ホーム
  2. ruby

[解決済み] Rubyで文字列を任意の長さのチャンクに分割する最良の方法は何ですか?

2023-01-18 22:06:24

質問

私はRubyで文字列を与えられた長さの部分文字列に分割するエレガントで効率的な方法を探しています。

今のところ、私が思いついた最高のものはこれです。

def chunk(string, size)
  (0..(string.length-1)/size).map{|i|string[i*size,size]}
end

>> chunk("abcdef",3)
=> ["abc", "def"]
>> chunk("abcde",3)
=> ["abc", "de"]
>> chunk("abc",3)
=> ["abc"]
>> chunk("ab",3)
=> ["ab"]
>> chunk("",3)
=> []

あなたは chunk("", n) を返すように [""] の代わりに [] . もしそうなら、メソッドの最初の行としてこれを追加するだけです。

return [""] if string.empty?

何か良い解決策はないでしょうか?

編集

このエレガントで効率的な解決策を提供してくれたJeremy Rutenに感謝します。[編集: 効率的ではありません!]

def chunk(string, size)
    string.scan(/.{1,#{size}}/)
end

編集

string.scanは512kを1kのチャンクに10000回分割するのに約60秒かかりますが、オリジナルのスライスベースのソリューションは2.4秒しかかかりせんでした。

どのように解決するのですか?

使用方法 String#scan :

>> 'abcdefghijklmnopqrstuvwxyz'.scan(/.{4}/)
=> ["abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx"]
>> 'abcdefghijklmnopqrstuvwxyz'.scan(/.{1,4}/)
=> ["abcd", "efgh", "ijkl", "mnop", "qrst", "uvwx", "yz"]
>> 'abcdefghijklmnopqrstuvwxyz'.scan(/.{1,3}/)
=> ["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]