Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
April 03, 2011 Re: Stuck with std.algorithm.splitter | ||||
---|---|---|---|---|
| ||||
Ok, here is my function which works as expected: --------------------------------------------------------------- string[] explode(in string source, char separator) { typeof(return) result; size_t prev = 0; foreach (i, c; source) { if (c == separator) { result ~= source[prev .. i]; prev = i + 1; } } result ~= source[prev .. $]; return result; } --------------------------------------------------------------- But, as I sad already, I would really like to use library function.. |
April 03, 2011 Re: Stuck with std.algorithm.splitter | ||||
---|---|---|---|---|
| ||||
On 2011-04-03 16:34, Aleksandar Ružičić wrote:
> I want to split a string into an array of strings. As much as it seems trivial I just can't make it work.
>
> This is code I use for splitting:
>
> -------------------------------------------------
> auto input = "foo|bar"; // sample input string auto parts = splitter(input, '|'); // split by pipe character
> -------------------------------------------------
>
> now, I would think that parts is an array. But it doesn't have .length property! Thus, I have to use walkLength:
>
> -------------------------------------------------
> if (walkLength(parts, 2) > 1) {
> writefln("%s, %s", parts[0], parts[1]);
> } else {
> writefln("%s", parts[0]);
> }
> -------------------------------------------------
>
> and problem with missing .length is gone, but now I cannot access those elements using array indexing:
>
> test.d(14): Error: no [] operator overload for type Splitter!(string,char)
> test.d(14): Error: no [] operator overload for type Splitter!(string,char)
> test.d(16): Error: no [] operator overload for type Splitter!(string,char)
>
> So, parts isn't an array but Splitter!(string,char), aha!
> But as much as I've tried I cannot find a way to access elements of
> Splitter by index. I've gone trough std.range and std.algorithm but
> found nothing useful...
>
> I would really like to use library function for this instead to write my own (foreach and array slicing comes to my mind)...
Splitter is not a random-access range. What type of range that it actually is depends on what it's splitting, but it doesn't appear to ever be a random- access range (which makes sense when you think about how it works). It's lazily splitting the range, so it _can't_ be random-access. If you want an actual array, then simply use array on it.
auto parts = array(splitter(input, '|'));
Then you'll have an array of strings to use. That _does_ copy the data though, so it's not something that you'd generally want to do if all you're doing is iterating through the result of splitter.
- Jonathan M Davis
|
April 04, 2011 Re: Stuck with std.algorithm.splitter | ||||
---|---|---|---|---|
| ||||
I definitely must sit down and read about ranges, as it seems I don't quite get what exactly they are (and what types of ranges exists and the difference between them).. > > auto parts = array(splitter(input, '|')); > That's a nice solution! I wasn't aware of array() though.. But I would like to avoid coping the data in this situation (I'm just interested in reading first one or two elements) so I'll be using explode() function I posted in previous email. Btw, I think that std.string could use function like this (explode, with possibly additional parameter to limit number of elements). At least by me, it's very commonly used function... > Then you'll have an array of strings to use. That _does_ copy the data though, so it's not something that you'd generally want to do if all you're doing is iterating through the result of splitter. > > - Jonathan M Davis > |
April 04, 2011 Re: Stuck with std.algorithm.splitter | ||||
---|---|---|---|---|
| ||||
On 2011-04-03 17:19, Aleksandar Ružičić wrote: > I definitely must sit down and read about ranges, as it seems I don't quite get what exactly they are (and what types of ranges exists and the difference between them).. > > > auto parts = array(splitter(input, '|')); > > That's a nice solution! I wasn't aware of array() though.. > But I would like to avoid coping the data in this situation (I'm just > interested in reading first one or two elements) so I'll be using > explode() function I posted in previous email. So, do auto parts = splitter(input, '|'); auto first = parts.front; parts.popFront(); auto second = parts.front; Now, I don't think that array is doing much of the way of copying anyway, since the result is an array of strings, and arrays are effectively reference types (so it's not like the whole string is getting copied), but if all you want to do is take the first couple of elements, then use the proper range functions for it. front accesses the first element of a range, and popFront removes the first element from the range. If you want to read about ranges, the original article is here: http://www.informit.com/articles/printerfriendly.aspx?p=1407357 It's not really D-specific though. I am currently work on an article on ranges in D (which I guess falls under Walter's article contest, though I started it before his announcement), but I don't know when it will be done (well before the contest's deadline of June 1st, but I don't know how soon), so maybe that will help you when that's done. In the meantime, the original article should give you a good, basic understanding of ranges, and if you look at the documentation for std.range and std.algorithm, hopefully that will help better understand how they're used. - Jonathan M Davis |
April 04, 2011 Re: Stuck with std.algorithm.splitter | ||||
---|---|---|---|---|
| ||||
On Mon, Apr 4, 2011 at 2:30 AM, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> On 2011-04-03 17:19, Aleksandar Ružičić wrote:
>> I definitely must sit down and read about ranges, as it seems I don't quite get what exactly they are (and what types of ranges exists and the difference between them)..
>>
>> > auto parts = array(splitter(input, '|'));
>>
>> That's a nice solution! I wasn't aware of array() though..
>> But I would like to avoid coping the data in this situation (I'm just
>> interested in reading first one or two elements) so I'll be using
>> explode() function I posted in previous email.
>
> So, do
>
> auto parts = splitter(input, '|');
> auto first = parts.front;
> parts.popFront();
> auto second = parts.front;
>
> Now, I don't think that array is doing much of the way of copying anyway, since the result is an array of strings, and arrays are effectively reference types (so it's not like the whole string is getting copied), but if all you want to do is take the first couple of elements, then use the proper range functions for it. front accesses the first element of a range, and popFront removes the first element from the range.
>
> If you want to read about ranges, the original article is here: http://www.informit.com/articles/printerfriendly.aspx?p=1407357
>
> It's not really D-specific though. I am currently work on an article on ranges in D (which I guess falls under Walter's article contest, though I started it before his announcement), but I don't know when it will be done (well before the contest's deadline of June 1st, but I don't know how soon), so maybe that will help you when that's done. In the meantime, the original article should give you a good, basic understanding of ranges, and if you look at the documentation for std.range and std.algorithm, hopefully that will help better understand how they're used.
>
> - Jonathan M Davis
>
Thank you. I've bookmarked the link and will read it in the morning! And I'll be waiting for your article too (although I hope Andrei's should help me understand the ranges enough to be able to use them).
|
Copyright © 1999-2021 by the D Language Foundation