digitalmars.D.learn - splitter for strings
- Chris (20/20) Jun 09 2014 Say I wanna split a string that contains hyphens. If I use
- bearophile (15/19) Jun 09 2014 With the current dmd 2.066alpha this code:
- Chris (2/21) Jun 09 2014 Ok, thanks. I'll keep that in mind for the next version.
- monarch_dodra (2/3) Jun 09 2014 Seems to me to also work with 2.065 and 2.064.
- Chris (15/19) Jun 09 2014 From the library reference:
- monarch_dodra (10/24) Jun 09 2014 You can just pipe in an extra "filter!(a=>!a.empty)", and it'll
- Chris (3/34) Jun 09 2014 I see, I've already popped in a filter. I only wonder how much of
- monarch_dodra (3/41) Jun 09 2014 Arguably, none, since someone has to do the check anyways. If
- Chris (4/46) Jun 09 2014 Yes, of course. I just thought if it's done in the library
- Steven Schveighoffer (9/28) Jun 09 2014 Right, it allows you to distinguish cases where the range starts or ends...
- Chris (12/50) Jun 09 2014 Atm, I have
- Steven Schveighoffer (9/15) Jun 09 2014 It's not mishandled. It's handled exactly as I would have expected. If
- Chris (15/35) Jun 09 2014 It is important. "blah--" should come out as "blah". The logic is
- monarch_dodra (5/46) Jun 09 2014 http://dlang.org/phobos/std_algorithm.html#strip
- Chris (4/53) Jun 09 2014 Uh, I see, I misread the signature of std.string.strip(). So
- monarch_dodra (5/8) Jun 09 2014 No, you read the documentation of std.*STRING*.strip correctly.
- Chris (2/10) Jun 09 2014 Ah, ok, talking about not seeing the forest for the trees ...
- monarch_dodra (3/7) Jun 09 2014 It's in algorithm, because it's more generic than just strings.
- Steven Schveighoffer (8/15) Jun 09 2014 Ugh.. This makes things difficult. If I want to work with strings, I
- monarch_dodra (9/26) Jun 09 2014 There's 2 different issues: The first, is that "split(string)"
- Steven Schveighoffer (14/42) Jun 09 2014 I think we are confusing things here, I was talking about strip :)
- monarch_dodra (29/34) Jun 09 2014 strip and split are actually both pretty much in the same boat
- Chris (6/42) Jun 09 2014 I think it makes sense to put any generic range based algorithms
- monarch_dodra (4/10) Jun 09 2014 Right, but "split(hello world)" *is* string specific. It makes
Say I wanna split a string that contains hyphens. If I use std.algorithm.splitter I end up with empty elements for each hyphen, e.g.: auto word = "bla-bla"; auto parts = appender!(string[]); w.splitter('-').copy(parts); // parts.data.length == 3 ["bla", "", "bla"] This is not ideal for my purposes, so I filter like so: auto parts = appender!(string[]); foreach (p; word.splitter('-')) { if (p != "") { parts ~= p; } } or even better like so: w.splitter('-').filter!(a => a != "").copy(parts); I wonder, however, whether this is ideal or whether regex's split would be a better match (pardon the pun!). I try to avoid regex when ever possible since they are more awkward to use and usually more expensive.
Jun 09 2014
Chris:auto word = "bla-bla"; auto parts = appender!(string[]); w.splitter('-').copy(parts); // parts.data.length == 3 ["bla", "", "bla"]With the current dmd 2.066alpha this code: void main() { import std.stdio, std.string, std.algorithm; const txt = "bla-bla"; txt.split("-").writeln; txt.splitter("-").writeln; txt.splitter('-').writeln; } Prints: ["bla", "bla"] ["bla", "bla"] ["bla", "bla"] Bye, bearophile
Jun 09 2014
On Monday, 9 June 2014 at 10:14:40 UTC, bearophile wrote:Chris:Ok, thanks. I'll keep that in mind for the next version.auto word = "bla-bla"; auto parts = appender!(string[]); w.splitter('-').copy(parts); // parts.data.length == 3 ["bla", "", "bla"]With the current dmd 2.066alpha this code: void main() { import std.stdio, std.string, std.algorithm; const txt = "bla-bla"; txt.split("-").writeln; txt.splitter("-").writeln; txt.splitter('-').writeln; } Prints: ["bla", "bla"] ["bla", "bla"] ["bla", "bla"] Bye, bearophile
Jun 09 2014
On Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:Ok, thanks. I'll keep that in mind for the next version.Seems to me to also work with 2.065 and 2.064.
Jun 09 2014
On Monday, 9 June 2014 at 10:54:09 UTC, monarch_dodra wrote:On Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:From the library reference: assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ])); and "If a range with one separator is given, the result is a range with two empty elements." My problem was that if I have input like auto word = "bla-"; it will return parts.data.length == 2, so I would have to check parts.data[1] != "". This is too awkward. I just want the parts of the word, i.e. length == 2 // grab [0] grab [1] length == 1 // grab [0] (no second part, as in "bla-") length > 2 // do something elseOk, thanks. I'll keep that in mind for the next version.Seems to me to also work with 2.065 and 2.064.
Jun 09 2014
On Monday, 9 June 2014 at 11:04:12 UTC, Chris wrote:From the library reference: assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ])); and "If a range with one separator is given, the result is a range with two empty elements." My problem was that if I have input like auto word = "bla-"; it will return parts.data.length == 2, so I would have to check parts.data[1] != "". This is too awkward. I just want the parts of the word, i.e. length == 2 // grab [0] grab [1] length == 1 // grab [0] (no second part, as in "bla-") length > 2 // do something elseYou can just pipe in an extra "filter!(a=>!a.empty)", and it'll do what you want: put(parts, w.splitter('-').filter!(a=>!a.empty)()); The rational for this behavior, is that it preserves the "total amount of information" from your input. EG: assert(equal(myString.spliter(sep).join(sep), myString)); If the empty tokens were all stripped out, that wouldn't work, you'd have lost information about how many separators there actually were, and where they were.
Jun 09 2014
On Monday, 9 June 2014 at 11:16:18 UTC, monarch_dodra wrote:On Monday, 9 June 2014 at 11:04:12 UTC, Chris wrote:I see, I've already popped in a filter. I only wonder how much of a performance loss that is. Probably negligible.From the library reference: assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ])); and "If a range with one separator is given, the result is a range with two empty elements." My problem was that if I have input like auto word = "bla-"; it will return parts.data.length == 2, so I would have to check parts.data[1] != "". This is too awkward. I just want the parts of the word, i.e. length == 2 // grab [0] grab [1] length == 1 // grab [0] (no second part, as in "bla-") length > 2 // do something elseYou can just pipe in an extra "filter!(a=>!a.empty)", and it'll do what you want: put(parts, w.splitter('-').filter!(a=>!a.empty)()); The rational for this behavior, is that it preserves the "total amount of information" from your input. EG: assert(equal(myString.spliter(sep).join(sep), myString)); If the empty tokens were all stripped out, that wouldn't work, you'd have lost information about how many separators there actually were, and where they were.
Jun 09 2014
On Monday, 9 June 2014 at 11:40:24 UTC, Chris wrote:On Monday, 9 June 2014 at 11:16:18 UTC, monarch_dodra wrote:Arguably, none, since someone has to do the check anyways. If it's not done "outside" of splitter, it has to be done inside...On Monday, 9 June 2014 at 11:04:12 UTC, Chris wrote:I see, I've already popped in a filter. I only wonder how much of a performance loss that is. Probably negligible.From the library reference: assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ])); and "If a range with one separator is given, the result is a range with two empty elements." My problem was that if I have input like auto word = "bla-"; it will return parts.data.length == 2, so I would have to check parts.data[1] != "". This is too awkward. I just want the parts of the word, i.e. length == 2 // grab [0] grab [1] length == 1 // grab [0] (no second part, as in "bla-") length > 2 // do something elseYou can just pipe in an extra "filter!(a=>!a.empty)", and it'll do what you want: put(parts, w.splitter('-').filter!(a=>!a.empty)()); The rational for this behavior, is that it preserves the "total amount of information" from your input. EG: assert(equal(myString.spliter(sep).join(sep), myString)); If the empty tokens were all stripped out, that wouldn't work, you'd have lost information about how many separators there actually were, and where they were.
Jun 09 2014
On Monday, 9 June 2014 at 12:16:30 UTC, monarch_dodra wrote:On Monday, 9 June 2014 at 11:40:24 UTC, Chris wrote:Yes, of course. I just thought if it's done in the library function, the optimization might be better than when it is done in my code. (filter!() is arguably also in the library :)On Monday, 9 June 2014 at 11:16:18 UTC, monarch_dodra wrote:Arguably, none, since someone has to do the check anyways. If it's not done "outside" of splitter, it has to be done inside...On Monday, 9 June 2014 at 11:04:12 UTC, Chris wrote:I see, I've already popped in a filter. I only wonder how much of a performance loss that is. Probably negligible.From the library reference: assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ])); and "If a range with one separator is given, the result is a range with two empty elements." My problem was that if I have input like auto word = "bla-"; it will return parts.data.length == 2, so I would have to check parts.data[1] != "". This is too awkward. I just want the parts of the word, i.e. length == 2 // grab [0] grab [1] length == 1 // grab [0] (no second part, as in "bla-") length > 2 // do something elseYou can just pipe in an extra "filter!(a=>!a.empty)", and it'll do what you want: put(parts, w.splitter('-').filter!(a=>!a.empty)()); The rational for this behavior, is that it preserves the "total amount of information" from your input. EG: assert(equal(myString.spliter(sep).join(sep), myString)); If the empty tokens were all stripped out, that wouldn't work, you'd have lost information about how many separators there actually were, and where they were.
Jun 09 2014
On Mon, 09 Jun 2014 07:04:11 -0400, Chris <wendlec tcd.ie> wrote:On Monday, 9 June 2014 at 10:54:09 UTC, monarch_dodra wrote:Note the 2 spaces between hello and worldOn Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:From the library reference: assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ]));Ok, thanks. I'll keep that in mind for the next version.Seems to me to also work with 2.065 and 2.064.and "If a range with one separator is given, the result is a range with two empty elements."Right, it allows you to distinguish cases where the range starts or ends with the separator.My problem was that if I have input like auto word = "bla-"; it will return parts.data.length == 2, so I would have to check parts.data[1] != "". This is too awkward. I just want the parts of the word, i.e. length == 2 // grab [0] grab [1] length == 1 // grab [0] (no second part, as in "bla-") length > 2 // do something elseOne thing you could do is strip any leading or trailing hyphens: assert("-bla-".chomp("-").chompPrefix("-").split('-').length == 1); Just looked at std.string for a strip function that allows custom character strippage, but apparently not there. The above is quite awkward. -Steve
Jun 09 2014
On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer wrote:On Mon, 09 Jun 2014 07:04:11 -0400, Chris <wendlec tcd.ie> wrote:Atm, I have auto parts = appender!(string[]); w.splitter('-').filter!(a => !a.empty).copy(parts); Which looks more elegant and gives me what I want. IMO, the module that handles the splitting of hyphenated words should be able to deal with cases like "blah-" without the input being prepared in a certain way. Now I have: if (parts.data.length == 1) { // false alarm. Trailing hyphen }On Monday, 9 June 2014 at 10:54:09 UTC, monarch_dodra wrote:Note the 2 spaces between hello and worldOn Monday, 9 June 2014 at 10:23:16 UTC, Chris wrote:From the library reference: assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ]));Ok, thanks. I'll keep that in mind for the next version.Seems to me to also work with 2.065 and 2.064.and "If a range with one separator is given, the result is a range with two empty elements."Right, it allows you to distinguish cases where the range starts or ends with the separator.My problem was that if I have input like auto word = "bla-"; it will return parts.data.length == 2, so I would have to check parts.data[1] != "". This is too awkward. I just want the parts of the word, i.e. length == 2 // grab [0] grab [1] length == 1 // grab [0] (no second part, as in "bla-") length > 2 // do something elseOne thing you could do is strip any leading or trailing hyphens: assert("-bla-".chomp("-").chompPrefix("-").split('-').length == 1); Just looked at std.string for a strip function that allows custom character strippage, but apparently not there. The above is quite awkward. -Steve
Jun 09 2014
On Mon, 09 Jun 2014 10:39:39 -0400, Chris <wendlec tcd.ie> wrote:Atm, I have auto parts = appender!(string[]); w.splitter('-').filter!(a => !a.empty).copy(parts); Which looks more elegant and gives me what I want. IMO, the module that handles the splitting of hyphenated words should be able to deal with cases like "blah-" without the input being prepared in a certain way.It's not mishandled. It's handled exactly as I would have expected. If "blah-" and "blah" result in the same thing, then how do you know the difference? Stripping any possible leading or trailing hyphens is much more efficient than checking every single word to see if it's empty. However, if you have an instance of "--", your solution will remove the extra empty string, whereas mine does not. Not sure if that's important. -Steve
Jun 09 2014
On Monday, 9 June 2014 at 14:47:45 UTC, Steven Schveighoffer wrote:On Mon, 09 Jun 2014 10:39:39 -0400, Chris <wendlec tcd.ie> wrote:It is important. "blah--" should come out as "blah". The logic is along the following lines: if (canFind(w, "-")) { auto parts = appender!(string[]); w.splitter('-').filter!(a => !a.empty).copy(parts); if (parts.data.length == 1) { // false alarm. Trailing hyphen } } The more common case is that it's not a trailing hyphen. std.string.strip() only works for whitespaces. Would be nice to have something like that for random characters. strip(s, '-') or strip(s, ['-', '+', ' '])Atm, I have auto parts = appender!(string[]); w.splitter('-').filter!(a => !a.empty).copy(parts); Which looks more elegant and gives me what I want. IMO, the module that handles the splitting of hyphenated words should be able to deal with cases like "blah-" without the input being prepared in a certain way.It's not mishandled. It's handled exactly as I would have expected. If "blah-" and "blah" result in the same thing, then how do you know the difference? Stripping any possible leading or trailing hyphens is much more efficient than checking every single word to see if it's empty. However, if you have an instance of "--", your solution will remove the extra empty string, whereas mine does not. Not sure if that's important. -Steve
Jun 09 2014
On Monday, 9 June 2014 at 15:19:05 UTC, Chris wrote:On Monday, 9 June 2014 at 14:47:45 UTC, Steven Schveighoffer wrote:http://dlang.org/phobos/std_algorithm.html#strip w = w.strip('-'); if (canFind(w, "-")) { ...On Mon, 09 Jun 2014 10:39:39 -0400, Chris <wendlec tcd.ie> wrote:It is important. "blah--" should come out as "blah". The logic is along the following lines: if (canFind(w, "-")) { auto parts = appender!(string[]); w.splitter('-').filter!(a => !a.empty).copy(parts); if (parts.data.length == 1) { // false alarm. Trailing hyphen } } The more common case is that it's not a trailing hyphen. std.string.strip() only works for whitespaces. Would be nice to have something like that for random characters. strip(s, '-') or strip(s, ['-', '+', ' '])Atm, I have auto parts = appender!(string[]); w.splitter('-').filter!(a => !a.empty).copy(parts); Which looks more elegant and gives me what I want. IMO, the module that handles the splitting of hyphenated words should be able to deal with cases like "blah-" without the input being prepared in a certain way.It's not mishandled. It's handled exactly as I would have expected. If "blah-" and "blah" result in the same thing, then how do you know the difference? Stripping any possible leading or trailing hyphens is much more efficient than checking every single word to see if it's empty. However, if you have an instance of "--", your solution will remove the extra empty string, whereas mine does not. Not sure if that's important. -Steve
Jun 09 2014
On Monday, 9 June 2014 at 15:52:24 UTC, monarch_dodra wrote:On Monday, 9 June 2014 at 15:19:05 UTC, Chris wrote:Uh, I see, I misread the signature of std.string.strip(). So that's one option now, to strip all trailing hyphens with std.string.strip(). Well, I'll give it a shot tomorrow.On Monday, 9 June 2014 at 14:47:45 UTC, Steven Schveighoffer wrote:http://dlang.org/phobos/std_algorithm.html#strip w = w.strip('-'); if (canFind(w, "-")) { ...On Mon, 09 Jun 2014 10:39:39 -0400, Chris <wendlec tcd.ie> wrote:It is important. "blah--" should come out as "blah". The logic is along the following lines: if (canFind(w, "-")) { auto parts = appender!(string[]); w.splitter('-').filter!(a => !a.empty).copy(parts); if (parts.data.length == 1) { // false alarm. Trailing hyphen } } The more common case is that it's not a trailing hyphen. std.string.strip() only works for whitespaces. Would be nice to have something like that for random characters. strip(s, '-') or strip(s, ['-', '+', ' '])Atm, I have auto parts = appender!(string[]); w.splitter('-').filter!(a => !a.empty).copy(parts); Which looks more elegant and gives me what I want. IMO, the module that handles the splitting of hyphenated words should be able to deal with cases like "blah-" without the input being prepared in a certain way.It's not mishandled. It's handled exactly as I would have expected. If "blah-" and "blah" result in the same thing, then how do you know the difference? Stripping any possible leading or trailing hyphens is much more efficient than checking every single word to see if it's empty. However, if you have an instance of "--", your solution will remove the extra empty string, whereas mine does not. Not sure if that's important. -Steve
Jun 09 2014
On Monday, 9 June 2014 at 19:47:29 UTC, Chris wrote:Uh, I see, I misread the signature of std.string.strip(). So that's one option now, to strip all trailing hyphens with std.string.strip(). Well, I'll give it a shot tomorrow.No, you read the documentation of std.*STRING*.strip correctly. I'm suggesting you use the one from std.*ALGORITHM*. The signatures are mutually exclusive, so you don't need to qualify them.
Jun 09 2014
On Monday, 9 June 2014 at 20:01:05 UTC, monarch_dodra wrote:On Monday, 9 June 2014 at 19:47:29 UTC, Chris wrote:Ah, ok, talking about not seeing the forest for the trees ...Uh, I see, I misread the signature of std.string.strip(). So that's one option now, to strip all trailing hyphens with std.string.strip(). Well, I'll give it a shot tomorrow.No, you read the documentation of std.*STRING*.strip correctly. I'm suggesting you use the one from std.*ALGORITHM*. The signatures are mutually exclusive, so you don't need to qualify them.
Jun 09 2014
On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer wrote:Just looked at std.string for a strip function that allows custom character strippage, but apparently not there. The above is quite awkward. -SteveIt's in algorithm, because it's more generic than just strings.
Jun 09 2014
On Mon, 09 Jun 2014 11:49:29 -0400, monarch_dodra <monarchdodra gmail.com> wrote:On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer wrote:Ugh.. This makes things difficult. If I want to work with strings, I import std.string. I understand that the algorithm is applicable to all types, but this makes for some awkward coding. What if you wanted to use both? Surely we can come up with a better solution than this. -SteveJust looked at std.string for a strip function that allows custom character strippage, but apparently not there. The above is quite awkward. -SteveIt's in algorithm, because it's more generic than just strings.
Jun 09 2014
On Monday, 9 June 2014 at 15:54:29 UTC, Steven Schveighoffer wrote:On Mon, 09 Jun 2014 11:49:29 -0400, monarch_dodra <monarchdodra gmail.com> wrote:There's 2 different issues: The first, is that "split(string)" was pre-existing in std.string, and *then* split was introduced in algorithm. Where ideally (?) everything would have been placed in the same module, we true to avoid moving things around now. The second thing is that "split" without any predicate/item can only make sense for strings, but not for generic ranges. For what it's worth, I find it makes sense.On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer wrote:Ugh.. This makes things difficult. If I want to work with strings, I import std.string. I understand that the algorithm is applicable to all types, but this makes for some awkward coding. What if you wanted to use both? Surely we can come up with a better solution than this. -SteveJust looked at std.string for a strip function that allows custom character strippage, but apparently not there. The above is quite awkward. -SteveIt's in algorithm, because it's more generic than just strings.
Jun 09 2014
On Mon, 09 Jun 2014 12:06:13 -0400, monarch_dodra <monarchdodra gmail.com> wrote:On Monday, 9 June 2014 at 15:54:29 UTC, Steven Schveighoffer wrote:I think we are confusing things here, I was talking about strip :)On Mon, 09 Jun 2014 11:49:29 -0400, monarch_dodra <monarchdodra gmail.com> wrote:On Monday, 9 June 2014 at 14:21:21 UTC, Steven Schveighoffer wrote:Ugh.. This makes things difficult. If I want to work with strings, I import std.string. I understand that the algorithm is applicable to all types, but this makes for some awkward coding. What if you wanted to use both? Surely we can come up with a better solution than this. -SteveJust looked at std.string for a strip function that allows custom character strippage, but apparently not there. The above is quite awkward. -SteveIt's in algorithm, because it's more generic than just strings.There's 2 different issues: The first, is that "split(string)" was pre-existing in std.string, and *then* split was introduced in algorithm. Where ideally (?) everything would have been placed in the same module, we true to avoid moving things around now. The second thing is that "split" without any predicate/item can only make sense for strings, but not for generic ranges. For what it's worth, I find it makes sense.Well, I suppose it should probably work if you try both strip and strip('-')... and indeed it does. It is not as bad as I thought (I thought they would conflict). It still leaves me a bit uneasy that std.string does not provide everything you would need to work with strings. But we don't want std.string importing std.algorithm, or at least we don't want it importing ALL of std.algorithm. If we could split up std.algorithm into individual modules, that would probably help. -Steve
Jun 09 2014
On Monday, 9 June 2014 at 17:57:24 UTC, Steven Schveighoffer wrote:I think we are confusing things here, I was talking about strip :)strip and split are actually both pretty much in the same boat actually in regards to that, so just 's/split/strip/g', and the same answer will apply. "split" (and "splitter") actually have it a bit more complicated, because historically, if you imported both string and algorithm, then "split(myString)" will create an ambiguous call. The issue is that you can't do selective imports when you already have a local object with the same name, so algorithm had: ---- auto split(String)(String myString) { return std.string.split(myString); } ---- rather than ---- public import std.string : split; ---- I tried to "fix" the issue by removing "split(String)" from algorithm, but that created some breakage. So Andrei just came down and put *everything* in algorithm, and added an "public import std.algorithm : split" in std.string. This works, but it does mean that: 1. string unconditionally pulls algorithm. 2. You can do things like: std.string.split([1, 2, 3], 2); IMO, the "strip" solution is better :/If we could split up std.algorithm into individual modules, that would probably help. -SteveYes.
Jun 09 2014
On Monday, 9 June 2014 at 18:09:07 UTC, monarch_dodra wrote:On Monday, 9 June 2014 at 17:57:24 UTC, Steven Schveighoffer wrote:I think it makes sense to put any generic range based algorithms (split and so forth) into std.algorithm. It's always my first port of call, when I have a range. However, that you can do std.string.split([1, 2, 3], 2); is not exactly a desirable situation.I think we are confusing things here, I was talking about strip :)strip and split are actually both pretty much in the same boat actually in regards to that, so just 's/split/strip/g', and the same answer will apply. "split" (and "splitter") actually have it a bit more complicated, because historically, if you imported both string and algorithm, then "split(myString)" will create an ambiguous call. The issue is that you can't do selective imports when you already have a local object with the same name, so algorithm had: ---- auto split(String)(String myString) { return std.string.split(myString); } ---- rather than ---- public import std.string : split; ---- I tried to "fix" the issue by removing "split(String)" from algorithm, but that created some breakage. So Andrei just came down and put *everything* in algorithm, and added an "public import std.algorithm : split" in std.string. This works, but it does mean that: 1. string unconditionally pulls algorithm. 2. You can do things like: std.string.split([1, 2, 3], 2); IMO, the "strip" solution is better :/If we could split up std.algorithm into individual modules, that would probably help. -SteveYes.
Jun 09 2014
On Monday, 9 June 2014 at 19:54:08 UTC, Chris wrote:I think it makes sense to put any generic range based algorithms (split and so forth) into std.algorithm. It's always my first port of call, when I have a range. However, that you can do std.string.split([1, 2, 3], 2); is not exactly a desirable situation.Right, but "split(hello world)" *is* string specific. It makes sense for strings only. It doens't make sense to write "split([1, 2, 3])", which is why I'm unsatisfied with the current situation.
Jun 09 2014