iteration over a string
Jonathan M Davis
jmdavisProg at gmx.com
Tue May 28 10:12:13 PDT 2013
On Tuesday, May 28, 2013 03:05:52 Timothee Cour wrote:
> 2A)
> Thanks for your answer;
>
> You skipped over this one, which I don't understand:
> > string a="ΩΩab";
> > auto b1=a.map!(a=>"<"d~a~">"d).array;
> > writeln(b1);//["<Ω>", "<Ω>", "<a>", "<b>", "", ""]
> > Why are there 2 empty strings at the end? (one per Omega if you vary the
>
> number of such symbols in the string).
>
> The above is just weird; is that a bug?
I didn't look into it, since I was in a hurry, but it definitely looks like a
bug.
> 2B)
>
> > The reason that we don't do that is mostly because it makes pretty much
>
> no sense to iterate over ranges of code units 99.99% of the time
>
> And yet "ΩΩab".map!foo seems to operate on code units and in order to
> operate on code points we need "ΩΩab".stride(1).map!foo, so isn't it
> inconsistent with the fact that std.algorithm.find("ΩΩab") operates on code
> points ?
Any and all range-based functions operate on code points when operating on
strings. If they do otherwise, it's a bug - probably due to a failed attempt
to optimize for strings.
> 2C)
>
> > Remember that ranges don't provide indices unless they're random access,
>
> For input ranges ranges, I don't understand why the compiler can't accept
> the foreach(i,ai;a) syntax:
>
> it should behave as follows:
> foreach(i , ai; a){expr}
>
> rewritten as:
> for(size_t i=0, ai=a.front; !a.empty; a.popFront;){expr}
>
> but it doesn't compile (it only accepts foreach(ai;a){expr}
foreach and ranges don't do anything with indices. I believe that the reason
that's usually brought up as to why is that for some types of ranges, it would
make no sense. There's probably an enhancement request open for it though as
it would certainly seem to make sense for most ranges. Though if you're
looking at the counter as being an index, it really doesn't make sense for
anything other than random-access ranges, as only they have indexing
operations.
In any case, if you're feeling fancy, you can use iota and zip to solve the
problem:
foreach(i, e; zip(iota(0, size_t.max), range))
{...}
and lockstep uses opApply to add an index, but it doesn't work with just one
range, so it wouldn't help with just giving foreach an index with normal range
iteration.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list