LoginSignup
0
0

More than 5 years have passed since last update.

リストを連結して文字列にする

Last updated at Posted at 2014-10-25

はじめに

Rubyのjoinみたいな関数がないので勉強のため書いてみました。
セパレータを挟んで連結する関数はRubyを使うときに、よく使用するのであれば便利だと思いました。

joinとは

Rubyの他にも様々な言語で実装されていると思いますが、今回はRubyを例にします。
処理内容は配列を受け取り、区切り文字で連結した文字列を返すというものです。
例として下にソースコードを示します。

join.rb
[1, 2, 3, 4].join(",")          # => "1,2,3,4"
['a', 'b', 'c', 'd'].join("=")        # => "a=b=c=d"

例のように配列を指定した区切り文字で連結して文字列を返しているのが分かります。
Rubyの実装では配列が入れ子になったものも平滑化して、関数を適用してくれます。Lispではリストの平滑化を行うflattenという関数を定義し、その関数を適用したリストを今回作成した関数に渡すと可能です。

ソースコード

join.lisp
(defun join (list sep)
 (with-output-to-string (s)
   (labels ((fn (list)
              (cond ((null (cdr list)) (princ (car list) s))
                    (t (princ (car list) s)
                       (princ sep s)
                       (fn (cdr list))))))
     (fn list))))
;=> JOIN

(join '(1 2 3 4) ",")
;=> "1,2,3,4"

(join '(a b c d) "=")
;=> "A=B=C=D"

(join '(a b c d) "===")
;=> "A===B===C===D"

おわりに

loopとformatで出来ると思ったのですが、最後に余計な区切り文字が入り、それを取り除く方法が分からなかったので諦めてしまいました。
Lispを勉強する前はループでまず解決しようと考えていたのですが、Lispを勉強し始めて再帰をまず使うような思考に切り替わったような気がします。

追記

doによるループでも実装してみました。

join_do.lisp
(defun join (list sep)
 (with-output-to-string (s)
   (do ((elem list (cdr elem)))
       ((null (cdr elem)) (princ (car elem) s))
     (princ (car elem) s)
     (princ sep s))))
;=> JOIN

(join '(1 2 3 4) ",")
;=> "1,2,3,4"

(join '(a b c d) "=")
;=> "A=B=C=D"

(join '(a b c d) "===")
;=> "A===B===C===D"
0
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0