Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std.algorithm.nWayUnion(Tuple) too? #9957

Open
dlangBugzillaToGithub opened this issue Feb 27, 2013 · 3 comments
Open

std.algorithm.nWayUnion(Tuple) too? #9957

dlangBugzillaToGithub opened this issue Feb 27, 2013 · 3 comments

Comments

@dlangBugzillaToGithub
Copy link

bearophile_hugs reported this on 2013-02-27T15:12:43Z

Transfered from https://issues.dlang.org/show_bug.cgi?id=9611

CC List

Description

In some cases I have had to merge ranges of different type. So maybe for such situations it's worth supporting nWayUnion of a Tuple of ranges:


import std.algorithm: nWayUnion, map;
import std.range: iota;
import std.typecons: tuple;
void main() {
    auto a = iota(10);
    auto b = [3, 6, 9];
    auto c = iota(11).map!q{a * a};
    auto r = nWayUnion(tuple(a, b, c));
}


Note: in all such of my usage cases the number of the ranges was limited, 2 or 3. So when the input of nWayUnion is a tuple I think there is no need for nWayUnion to keep the ranges inside with a BinaryHeap.

- - - - - - - - - - - - - -

Current workaround, suggested by Ali Çehreli:

import std.algorithm: nWayUnion, map;
import std.range: iota, InputRange, inputRangeObject;
void main() {
    InputRange!int a = inputRangeObject(iota(10));
    InputRange!int b = inputRangeObject([3, 6, 9]);
    InputRange!int c = inputRangeObject(iota(11).map!q{a * a});
    auto r = nWayUnion([a, b, c]);
}
@dlangBugzillaToGithub
Copy link
Author

zshazz commented on 2013-02-27T17:13:37Z

(In reply to comment #0)
> Current workaround, suggested by Ali Çehreli:
> 
> import std.algorithm: nWayUnion, map;
> import std.range: iota, InputRange, inputRangeObject;
> void main() {
>     InputRange!int a = inputRangeObject(iota(10));
>     InputRange!int b = inputRangeObject([3, 6, 9]);
>     InputRange!int c = inputRangeObject(iota(11).map!q{a * a});
>     auto r = nWayUnion([a, b, c]);
> }

A function that does the conversion to InputRange!E could easily be created and added to Phobos to handle this type of situation. Ranges such as nWayUnion could call this (currently poorly named) tupWrapper when isTuple!T returns true.

---

import std.stdio, std.range, std.typecons, std.algorithm;

void main() {
	auto tup = tuple(iota(5), repeat(1).take(3), [5,9,30]);

	foreach(e; tupWrapper(tup).nWayUnion())
		writeln(e);
}

auto tupWrapper(Tup)(Tup tup) {
	alias E = ElementType!(Tup.Types[0]);
	InputRange!E[] arr;
	foreach(T; Tup.Types)
		static assert(is(ElementType!T == E));

	foreach(ref e; tup)
		arr ~= inputRangeObject(e);

	return arr;
}

---

Currently, that solution isn't too robust. Ideally it would figure out the most powerful range type (either InputRange, ForwardRange, ..., RandomAccessRange) that all the types in the Tuple.Types support and it would return that.

@dlangBugzillaToGithub
Copy link
Author

bearophile_hugs commented on 2013-02-27T17:24:55Z

(In reply to comment #1)

> A function that does the conversion to InputRange!E could easily be created and
> added to Phobos to handle this type of situation.

I think InputRange and inputRangeObject are not needed to solve this. A "static foreach" on the Tuple fields (that contain ranges) looking for the smallest value seems enough to me.

@dlangBugzillaToGithub
Copy link
Author

andrei (@andralex) commented on 2013-02-27T17:43:45Z

Yah, this should be added. Suffice to add a one-argument member function to SortedRange.

@LightBender LightBender removed the P4 label Dec 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants