challenge 擬似lsの実装

スラッシュで区切られた文字列の配列(以下パスリスト)がある。
このパスリストにたいして擬似的なlsを行いたい。
lsはパスリストと表示対象ディレクトリのパスを入力する。

例としては以下のようになる。
pathList = ["aaa/bbb","aaa/ccc","aaa/ddd/eee","bbb/ddd/eee"]

ls(pathList,"aaa/")
>["bbb","ccc","ddd/"]

ls(pathList,"aaa/ddd/")
>["eee"]

なおパスリストが大きくなったとき、速度がなるべく低下しないように実装するのが望ましい。
文字列は任意の文字コードであると仮定してかまわない。

Posted feedbacks - Common Lisp

第一引数の文字列の末尾は "/" ではなく、 第二引数の末尾は "/" であることを仮定しています。

やり方はまあ普通です。リスト生成に mapcan を使ってみました。

1
2
3
4
5
6
7
8
(defun ls (files dir)
  (let ((len (length dir)))
    (mapcan (lambda (f)
              (and (>= (length f) len)
                   (string= f dir :end1 len)
                   (let ((p (position #\/ f :start len)))
                     (list (subseq f len (and p (1+ p)))))))
            files)))

が、ループの方が簡潔に書けました。それと、都合のいい入力を仮定するなら mismatch でよさそう。

1
2
3
4
5
6
(defun ls (files dir)
  (loop with len = (length dir)
    for f in files
    if (= (mismatch f dir) len)
    collect (let ((p (position #\/ f :start len)))
              (subseq f len (and p (1+ p))))))

初めての投稿です。

cl-ppcreで正規表現を使ってみたかっただけです。
cl-ppcreが入っていない環境では動作しません。

第二引数は/で終わっていない場合にはnilを返すようにしてます。
1
2
3
4
5
6
7
8
(asdf:oos 'asdf:load-op :cl-ppcre)
(defun ls (pathlist path)
  (let ((res nil))
    (if (cl-ppcre:scan "(.*)/" path) 
    (dolist (i pathlist res)
      (multiple-value-bind (s e) (cl-ppcre:scan  path  i) 
        (if (and s (= s '0) e) 
        (setq res (cons  (subseq i  e) res))))))))

Index

Feed

Other

Link

Pathtraq

loading...