Thread overview
Is there a smart way to process a range of range by front ?
Sep 23, 2015
BBasile
Sep 23, 2015
Justin Whear
Sep 23, 2015
BBasile
Sep 23, 2015
BBasile
Sep 23, 2015
Justin Whear
Sep 23, 2015
BBasile
Sep 23, 2015
Martin Nowak
September 23, 2015
I was thinking to a general *interleave()* algorithm for any compatible Range of Range but I can't find any smart way to process each sub range by front, eg:

---
void interleave(RoR)(RoR r)
{
   r.each!(a => a.writeln);
}

void main()
{
    auto r = [[0,2],[1,3]];
    interleave(r);
}
---

will print:
[0,2]
[1,3]

while to interleave i need to take the front of each sub range before poping each ror element.

Currently I'm here (don't run this ;)) :

---
auto interleave(RoR)(RoR r)
{
    alias T = ElementType!r[0];
    T[] result;
    while (!empty(r[0]))
        r.each!(a => (result ~= a.front, a.popFront));
    return result;
}

void main()
{
    auto r = [[0,2],[1,3]];
    interleave(r);
}
---

but it doesn't work because 'a' is not consumed. It looks like it's saved from the input parameter at each iteration of the while loop hence it never returns.

Is it possible ?
September 23, 2015
On Wed, 23 Sep 2015 20:48:03 +0000, BBasile wrote:

> I was thinking to a general *interleave()* algorithm for any compatible Range of Range but I can't find any smart way to process each sub range by front

Can you show a sample input and output to clarify what you mean by interleave?  It's possible that what you want is std.range.frontTransversal, std.range.transversal, or std.range.transposed.
September 23, 2015
On Wednesday, 23 September 2015 at 21:04:44 UTC, Justin Whear wrote:
> On Wed, 23 Sep 2015 20:48:03 +0000, BBasile wrote:
>
>> I was thinking to a general *interleave()* algorithm for any compatible Range of Range but I can't find any smart way to process each sub range by front
>
> Can you show a sample input and output to clarify what you mean by interleave?  It's possible that what you want is std.range.frontTransversal, std.range.transversal, or std.range.transposed.

---
auto r0 = [[0,2],[1,3]];
auto r1 = interleave(r0);
assert(r1 = [0,1,2,3]);
auto r2 = [[0,3],[1,4],[2,5]];
auto r3 = interleave(r2);
assert(r3 = [0,1,2,3,4,5]);
---

the fact that the numbers are ordered is just an helper.


September 23, 2015
On Wednesday, 23 September 2015 at 21:17:29 UTC, BBasile wrote:
> On Wednesday, 23 September 2015 at 21:04:44 UTC, Justin Whear wrote:
>> On Wed, 23 Sep 2015 20:48:03 +0000, BBasile wrote:
>>
>>> I was thinking to a general *interleave()* algorithm for any compatible Range of Range but I can't find any smart way to process each sub range by front
>>
>> Can you show a sample input and output to clarify what you mean by interleave?  It's possible that what you want is std.range.frontTransversal, std.range.transversal, or std.range.transposed.
>
> ---
> auto r0 = [[0,2],[1,3]];
> auto r1 = interleave(r0);
> assert(r1 = [0,1,2,3]);
> auto r2 = [[0,3],[1,4],[2,5]];
> auto r3 = interleave(r2);
> assert(r3 = [0,1,2,3,4,5]);
> ---
>
> the fact that the numbers are ordered is just an helper.

just imagine that there are double equal symbols in the assertions...
September 23, 2015
On Wed, 23 Sep 2015 21:17:27 +0000, BBasile wrote:

> On Wednesday, 23 September 2015 at 21:04:44 UTC, Justin Whear wrote:
>> On Wed, 23 Sep 2015 20:48:03 +0000, BBasile wrote:
>>
>>> I was thinking to a general *interleave()* algorithm for any compatible Range of Range but I can't find any smart way to process each sub range by front
>>
>> Can you show a sample input and output to clarify what you mean by interleave?  It's possible that what you want is std.range.frontTransversal, std.range.transversal, or std.range.transposed.
> 
> ---
> auto r0 = [[0,2],[1,3]];
> auto r1 = interleave(r0);
> assert(r1 = [0,1,2,3]);
> auto r2 = [[0,3],[1,4],[2,5]];
> auto r3 = interleave(r2);
> assert(r3 = [0,1,2,3,4,5]);
> ---
> 
> the fact that the numbers are ordered is just an helper.

OK, I think what you're after is std.range.roundRobin.
September 23, 2015
On Wednesday, 23 September 2015 at 21:24:22 UTC, Justin Whear wrote:
> On Wed, 23 Sep 2015 21:17:27 +0000, BBasile wrote:
>
>> On Wednesday, 23 September 2015 at 21:04:44 UTC, Justin Whear wrote:
>>> On Wed, 23 Sep 2015 20:48:03 +0000, BBasile wrote:
>>>
>>>> I was thinking to a general *interleave()* algorithm for any compatible Range of Range but I can't find any smart way to process each sub range by front
>>>
>>> Can you show a sample input and output to clarify what you mean by interleave?  It's possible that what you want is std.range.frontTransversal, std.range.transversal, or std.range.transposed.
>> 
>> ---
>> auto r0 = [[0,2],[1,3]];
>> auto r1 = interleave(r0);
>> assert(r1 = [0,1,2,3]);
>> auto r2 = [[0,3],[1,4],[2,5]];
>> auto r3 = interleave(r2);
>> assert(r3 = [0,1,2,3,4,5]);
>> ---
>> 
>> the fact that the numbers are ordered is just an helper.
>
> OK, I think what you're after is std.range.roundRobin.

---
import std.range;

auto interleave(RoR)(RoR r)
{
    return r.transposed.join;
}

void main()
{
    auto r0 = [[0,2],[1,3]];
    auto r1 = interleave(r0);
    assert(r1 == [0,1,2,3]);
    auto r2 = [[0,3],[1,4],[2,5]];
    auto r3 = interleave(r2);
    assert(r3 == [0,1,2,3,4,5]);
}
--

thx, but as you was suposing initially 'transposed' works.
didn't know this function before. works fine.
September 23, 2015
On Wednesday, 23 September 2015 at 21:30:37 UTC, BBasile wrote:
> auto interleave(RoR)(RoR r)
> {
>     return r.transposed.join;

If you use joiner it will even be lazy and avoid the allocation.