Last active
December 11, 2016 17:52
-
-
Save lispm/71fa971416307905b9c2b7a2beee55e9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ; https://github.com/alandipert/dotfiles/blob/master/dotfiles/bash/abbrev_pwd.lisp | |
| ; original | |
| ; splits string into a vector of strings | |
| (defun split-string (str delim-char) | |
| (let* ((num-delims 2) | |
| (delim-idxs (loop with idxs = (list (length str)) | |
| for idx from (1- (length str)) downto 0 | |
| when (eq (elt str idx) delim-char) | |
| do (setq idxs (cons idx idxs) | |
| num-delims (1+ num-delims)) | |
| finally (return (cons -1 idxs))))) | |
| (loop with parts = (make-array (1- num-delims) :fill-pointer 0) | |
| for idxs on delim-idxs by #'cdr | |
| for (x y) = idxs | |
| when y | |
| do (vector-push (subseq str (1+ x) y) parts) | |
| finally (return parts)))) | |
| ; list-based version | |
| ; splits a vector into a list of strings | |
| (defun character-indices (string character) | |
| "Returns a list of indices where the character occurs in the string" | |
| (loop for element across string and index from 0 | |
| when (eql element character) | |
| collect index)) | |
| (defun split-string (string delim-char) | |
| "Returns a list of strings, split at the delimiter character. | |
| For delimiter character at the beginning or the end of the string, | |
| an empty string is collected in the result." | |
| (loop for (x y) on (cons -1 (character-indices string delim-char)) | |
| collect (subseq string | |
| (1+ x) | |
| (or y (length string))))) | |
| ; function from above using CHAR accessor | |
| (defun character-indices (string character) | |
| (loop for i below (length string) | |
| when (eql (char string i) character) | |
| collect i)) | |
| ; using POSITION to find the characters | |
| (defun split-string (string delim-char) | |
| (loop for (x y) on (loop for pos = -1 then (position delim-char string :start (1+ pos)) | |
| collect (or pos (length string)) | |
| while pos) | |
| while y | |
| collect (subseq string (1+ x) y))) | |
| ;;; do it all in one LOOP using POSITION | |
| ; advantages over the original: | |
| ; * shorter code | |
| ; * less variables | |
| ; * no custom collection operations | |
| ; * left to right processing | |
| ; * no intermediate list | |
| ; * no nested LOOPs | |
| (defun split-string (string delim-char) | |
| (loop for pos0 = -1 then pos1 | |
| for pos1 = (position delim-char string :start (1+ pos0)) | |
| collect (subseq string (1+ pos0) (or pos1 (length string))) | |
| while pos1)) | |
| ; the above in old-style Lisp using DO* | |
| (defun split-string (string delim-char &aux result) | |
| (do* ((pos0 -1 pos1) | |
| (pos1 (position delim-char string) | |
| (and pos0 (position delim-char string :start (1+ pos0))))) | |
| ((not pos0) (nreverse result)) | |
| (push (subseq string (1+ pos0) (or pos1 (length string))) | |
| result))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment