I think we need something like these in Phobos -- I was quite
surprised that I didn't find these in Phobos. They're really
handy in Python.
auto groupby(alias Key = k => k, alias Value = v => v, alias
Equal = (a, b) => a == b, R)(R range)
if (isInputRange!(R))
{
struct GroupBy
{
alias typeof(Key(R.init.front)) TKey;
R r;
@property bool empty() { return this.r.empty; }
void popFront()
{
auto k = Key(this.r.front);
this.r.popFront();
while (!this.r.empty && Equal(k, Key(this.r.front)))
{ this.r.popFront(); }
}
@property auto front()
{
TKey k = Key(this.r.front);
struct Grouper
{
TKey k;
R r;
@property bool empty()
{ return this.r.empty || !Equal(this.k,
Key(this.r.front)); }
void popFront() { this.r.popFront(); }
@property auto front()
{ return Value(this.r.front); }
}
return Grouper(k, this.r);
}
static if (isForwardRange!(R))
{ @property typeof(this) save() { return
typeof(this)(this.r.save()); } }
}
return GroupBy(range);
}
auto dict(R)(R range)
{
ElementType!(R)[typeof(ElementType!(R).init[0])] result;
foreach (t; range) { result[t[0]] = t /* or t[1]? */; }
return result;
}
auto sorted(alias F = q{a < b}, SwapStrategy S =
SwapStrategy.unstable, R)(R range)
{
auto arr = range.array();
arr.sort!(F, S)();
return arr;
}
Ideas?