[Gd-chatter] r11649 - in trunk/libraries/strings: . tests
cgay at gwydiondylan.org
cgay at gwydiondylan.org
Mon Jan 21 14:13:01 CET 2008
Author: cgay
Date: Mon Jan 21 14:13:00 2008
New Revision: 11649
Modified:
trunk/libraries/strings/strings.dylan
trunk/libraries/strings/tests/strings-test-suite.dylan
Log:
job: minor
better join
Modified: trunk/libraries/strings/strings.dylan
==============================================================================
--- trunk/libraries/strings/strings.dylan (original)
+++ trunk/libraries/strings/strings.dylan Mon Jan 21 14:13:00 2008
@@ -39,9 +39,6 @@
define open generic trim (string :: <string>, #key) => (new-string :: <string>);
-define open generic join
- (items :: <sequence>, separator :: <string>, #key) => (new-string :: <string>);
-
define open generic replace
(original :: <string>, pattern :: <object>, replacement :: <string>, #key)
=> (new-string :: <string>, num-replacements :: <integer>);
@@ -783,35 +780,62 @@
end method digit-to-integer;
// ----------------------------------------------------------------------
+define open generic join
+ (items :: <sequence>, separator :: <sequence>, #key key, conjunction)
+ => (joined :: <sequence>);
+
// join(range(from: 1, to: 3), ", ",
// key: integer-to-string,
// conjunction: " and ");
// => "1, 2 and 3"
define method join
- (seq :: <sequence>, separator :: <string>,
+ (sequences :: <sequence>, separator :: <sequence>,
#key key :: <function> = identity,
- conjunction :: false-or(<string>))
- => (result :: <string>)
- with-output-to-string (out)
- let len-1 :: <integer> = seq.size - 1;
- for (i :: <integer> from 1,
- item in seq)
- let v = key(item);
- select (v by instance?)
- <string> => write(out, v);
- <character> => write-element(out, v);
- otherwise => write(out, as(<string>, v));
- end;
- //write(out, as(<string>, key(item)));
- if (i < len-1)
- write(out, separator);
- elseif (i == len-1)
- write(out, conjunction | separator);
- end;
+ conjunction :: false-or(<sequence>))
+ => (joined :: <sequence>)
+ let length :: <integer> = sequences.size;
+ if (length == 0)
+ error("Attempt to join an empty sequence.")
+ elseif (length == 1)
+ key(sequences[0])
+ else
+ let result-size :: <integer>
+ = (reduce(method (len, seq)
+ len + seq.size
+ end,
+ 0,
+ sequences)
+ + (separator.size * (length - 1))
+ + if (conjunction)
+ // the last separator is replaced by the conjunction
+ conjunction.size - separator.size
+ else
+ 0
+ end);
+ let first = key(sequences[0]); // don't call key > once on sequences[0]
+ let result = make(object-class(first), size: result-size);
+ let result-index :: <integer> = 0;
+ local method copy-to-result (seq :: <sequence>)
+ result := replace-subsequence!(result, seq, start: result-index);
+ result-index := result-index + seq.size;
+ end;
+ copy-to-result(first);
+ let max-index :: <integer> = length - 1;
+ for (i :: <integer> from 1 to max-index)
+ let seq :: <sequence> = sequences[i];
+ copy-to-result(if(conjunction & i == max-index)
+ conjunction
+ else
+ separator
+ end);
+ copy-to-result(key(seq));
end;
- end
+ result
+ end if
end method join;
+
+
// In common-dylan library...
// Split a sequence into parts at each occurrance of the 'separator'
Modified: trunk/libraries/strings/tests/strings-test-suite.dylan
==============================================================================
--- trunk/libraries/strings/tests/strings-test-suite.dylan (original)
+++ trunk/libraries/strings/tests/strings-test-suite.dylan Mon Jan 21 14:13:00 2008
@@ -208,17 +208,19 @@
end function-test trim;
define strings function-test join ()
- for (item in list(list(list("", "-"), ""),
- list(list(#("a", "b", "c"), "-"), "a-b-c"),
- list(list(#("a", "b", "c"), ", ", conjunction:, " and "),
- "a, b and c"),
- list(list("abc", ", ", conjunction:, " and ", key:, uppercase),
- "A, B and C")))
- let (join-args, expected-result) = apply(values, item);
- let test-name = fmt("join(%s)",
- join(join-args, ", ", key: method (x) fmt("%=", x) end));
- check-equal(test-name, apply(join, join-args), expected-result);
- end for;
+ let abc = #["a", "b", "c"];
+ check-equal("join one element", join(#["foo"], "-"), "foo");
+ check-equal("join with empty separator", join(abc, ""), "abc");
+ check-equal("join with non-empty separator", join(abc, "-"), "a-b-c");
+ check-equal("join with conjunction",
+ join(abc, ", ", conjunction: " and "),
+ "a, b and c");
+ check-equal("join with conjunction and key",
+ join(abc, ", ", conjunction: " and ", key: uppercase),
+ "A, B and C");
+ check-condition("join an empty sequence is an error",
+ <error>,
+ join(#[], "-"));
end function-test join;
define strings function-test integer-to-digit ()
More information about the chatter
mailing list