Isn't using find with retro awkward?
Steven Schveighoffer
schveiguy at yahoo.com
Wed Feb 16 11:40:49 PST 2011
On Wed, 16 Feb 2011 14:24:36 -0500, Andrej Mitrovic
<andrej.mitrovich at gmail.com> wrote:
> The only thing I could come up with is exhausting the entire range to
> get the length of a bidirectional range. But that's inefficient.
> Anyway here's the dull thing:
>
> import std.stdio;
> import std.range;
> import std.array;
>
> R findBack(alias pred = "a == b", R, E)(R haystack, E needle)
> if (isBidirectionalRange!R)
> {
> size_t index;
> bool found;
> auto saved = haystack;
>
> foreach (item; retro(haystack))
> {
> if (item == needle)
> {
> found = true;
> index++;
> break;
> }
> index++;
> }
>
> if (found)
> {
> size_t newIndex;
> while (!haystack.empty)
> {
> newIndex++;
> haystack.popBack;
> }
>
> newIndex -= index;
> while (!saved.empty && newIndex)
> {
> saved.popFront;
> newIndex--;
> }
> }
>
> return saved;
> }
>
> void main()
> {
> auto orig = [4, 0, 4, 0];
> auto result = findBack(orig, 4);
>
> assert(array(result) == [4, 0]);
>
> result.front = 10;
> assert(orig == [4, 0, 10, 0]);
> }
>
> You'll have to forgive me but I have yet to study algorithms properly. :)
Hehe if you are willing to traverse the whole range, it's much easier than
this:
auto saved = R.init;
while(!haystack.empty)
{
if(haystack.front == needle)
saved = haystack.save();
haystack.popFront();
}
return saved;
The point is, no matter what you do, the missing ability to construct a
range from two iterators/cursors means you must degrade performance to get
the desired effect.
This might be able to be simulated with having a range "flip" itself based
on certain criteria, but it must be a range-supported feature, which means
more complexity goes into the range concept.
-Steve
More information about the Digitalmars-d-learn
mailing list