Skip to content

Instantly share code, notes, and snippets.

@kurohuku
Created August 4, 2010 07:05
Show Gist options
  • Save kurohuku/507774 to your computer and use it in GitHub Desktop.
Save kurohuku/507774 to your computer and use it in GitHub Desktop.
;;; loop
(defun split-str-1 (str sep)
(labels ((sep? (ch)
(typecase sep
(function
(funcall sep ch))
(list (find ch sep))
(sequence (find ch sep))
(atom (eq sep ch))
(T nil))))
(let ((result nil)
(tmp nil))
(loop
:for ch across str
:do
(if (sep? ch)
(when tmp
(push (coerce (nreverse tmp) 'string)result)
(setf tmp nil))
(push ch tmp)))
(when tmp
(push (coerce (nreverse tmp) 'string) result))
(nreverse result))))
;;; tail recursion
(defun split-str-2 (str sep)
(let ((len (length str)))
(labels ((sep? (ch)
(typecase sep
(function
(funcall sep ch))
(list (find ch sep))
(sequence (find ch sep))
(atom (eq sep ch))
(T nil)))
(inner (pos tmp acc)
(if (= len pos)
(nreverse
(mapcar #'(lambda (x) (nreverse (coerce x 'string)))
(if tmp (cons tmp acc) acc)))
(let ((ch (elt str pos)))
(if (sep? ch)
(inner (1+ pos) nil (if tmp (cons tmp acc) acc))
(inner (1+ pos) (cons ch tmp) acc))))))
(inner 0 nil nil))))
;;; subseq
(defun split-str-3 (str sep)
(let ((len (length str)))
(labels ((sep? (ch)
(typecase sep
(function
(funcall sep ch))
(list (find ch sep))
(sequence (find ch sep))
(atom (eq sep ch))
(T nil)))
(inner (pos start acc)
(if (= len pos)
(reverse (if (/= pos start) (cons (subseq str start pos) acc) acc))
(if (sep? (elt str pos))
(inner (1+ pos) (1+ pos)
(if (= pos start) acc
(cons (subseq str start pos) acc)))
(inner (1+ pos) start acc)))))
(inner 0 0 nil))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment