Browse code
Have split handle empty strings appropriately.
Showing 2 changed files
... | ... |
@@ -49,7 +49,8 @@ |
49 | 49 |
|
50 | 50 |
;; TODO: implement test |
51 | 51 |
(defun %split-on-char (divider string &key count (test nil)) |
52 |
- (declare (optimize #+dev (debug 3) (speed 3) (space 2)) |
|
52 |
+ (declare (optimize #+dev (debug 3) #+dev (speed 0) #+dev (space 0) |
|
53 |
+ #-dev (speed 3) #-dev(space 2)) |
|
53 | 54 |
(type (or null array-length) count) |
54 | 55 |
(type (or null function symbol) test) |
55 | 56 |
(type character divider) |
... | ... |
@@ -60,21 +61,25 @@ |
60 | 61 |
(check-type string simple-string) |
61 | 62 |
|
62 | 63 |
(flet ((count-splits (string) |
63 |
- (declare (optimize (speed 3)) |
|
64 |
+ (declare (optimize #+dev (debug 3) #+dev (speed 0) #+dev (space 0) |
|
65 |
+ #-dev (speed 3) #-dev(space 2)) |
|
64 | 66 |
(type simple-string string)) |
65 |
- (do* ((x (the array-length 0) (1+ x)) |
|
66 |
- (cur-char #1=(aref string x) #1#) |
|
67 |
- (result (the array-length |
|
68 |
- (if (char= cur-char divider) |
|
69 |
- 1 |
|
70 |
- 0)) |
|
71 |
- (if (char= cur-char divider) |
|
72 |
- (1+ result) |
|
73 |
- result))) |
|
74 |
- ((= x (1- (length string))) (1+ result)) |
|
75 |
- (declare (type array-length result)))) |
|
67 |
+ (if (/= 0 (length string)) |
|
68 |
+ (do* ((x (the array-length 0) (1+ x)) |
|
69 |
+ (cur-char #1=(aref string x) #1#) |
|
70 |
+ (result (the array-length |
|
71 |
+ (if (char= cur-char divider) |
|
72 |
+ 1 |
|
73 |
+ 0)) |
|
74 |
+ (if (char= cur-char divider) |
|
75 |
+ (1+ result) |
|
76 |
+ result))) |
|
77 |
+ ((= x (1- (length string))) (1+ result)) |
|
78 |
+ (declare (type array-length result))) |
|
79 |
+ 0)) |
|
76 | 80 |
(find-pos (start-pos) |
77 |
- (declare (optimize (speed 3)) |
|
81 |
+ (declare (optimize #+dev (debug 3) #+dev (speed 0) #+dev (space 0) |
|
82 |
+ #-dev (speed 3) #-dev(space 2)) |
|
78 | 83 |
(type array-index start-pos)) |
79 | 84 |
(etypecase test |
80 | 85 |
(function (position divider string :start start-pos :test test)) |
... | ... |
@@ -85,7 +90,7 @@ |
85 | 90 |
(setf count (count-splits string))) |
86 | 91 |
|
87 | 92 |
(check-type count array-length) |
88 |
- (let ((parts (make-array count :fill-pointer 0)) |
|
93 |
+ (let ((parts (make-array (max count 1) :fill-pointer 0)) |
|
89 | 94 |
(start-pos (the fixnum 0))) |
90 | 95 |
(declare (dynamic-extent start-pos)) |
91 | 96 |
(prog1 parts |
... | ... |
@@ -97,10 +102,11 @@ |
97 | 102 |
(setf start-pos (1+ end-pos)) |
98 | 103 |
while (< (length parts) (1- count)) |
99 | 104 |
finally |
100 |
- (when (and end-pos count) |
|
101 |
- (vector-push (subseq string start-pos) |
|
102 |
- parts)) |
|
103 |
- ))))) |
|
105 |
+ (cond ((and end-pos count) |
|
106 |
+ (vector-push (subseq string start-pos) |
|
107 |
+ parts)) |
|
108 |
+ ((not end-pos) |
|
109 |
+ (vector-push "" parts)))))))) |
|
104 | 110 |
|
105 | 111 |
(defun %split-on-string (divider string &key count (test nil)) |
106 | 112 |
(declare (optimize #+dev (debug 3) (speed 3)) |
... | ... |
@@ -1,7 +1,9 @@ |
1 | 1 |
(in-package :fwoar.string-utils) |
2 | 2 |
|
3 | 3 |
(defun vos-equal (a b) |
4 |
- (every 'equal a b)) |
|
4 |
+ (and (= (length a) |
|
5 |
+ (length b)) |
|
6 |
+ (every 'equal a b))) |
|
5 | 7 |
|
6 | 8 |
(progn |
7 | 9 |
(st:deftest string-split-as-expected-with-test () |
... | ... |
@@ -36,6 +38,10 @@ |
36 | 38 |
(st:should be vos-equal |
37 | 39 |
#("a" "b" "c" "d") |
38 | 40 |
(%split-on-string " " "a b c d"))) |
41 |
+ (st:deftest string-split-empty-string-as-expected () |
|
42 |
+ (st:should be vos-equal |
|
43 |
+ #("") |
|
44 |
+ (%split-on-string "/" ""))) |
|
39 | 45 |
|
40 | 46 |
(st:deftest char-split-as-expected-with-test () |
41 | 47 |
(st:should be vos-equal |
... | ... |
@@ -65,4 +71,9 @@ |
65 | 71 |
(st:should be vos-equal |
66 | 72 |
#("a" "b" "c" "d") |
67 | 73 |
(%split-on-char #\space "a b c d"))) |
74 |
+ |
|
75 |
+ (st:deftest char-split-empty-string-as-expected () |
|
76 |
+ (st:should be vos-equal |
|
77 |
+ #("") |
|
78 |
+ (%split-on-char #\/ ""))) |
|
68 | 79 |
) |