Thread overview
Using std.algorithm how to uniq and sort a multidimensional array?
Jan 28, 2014
Gary Willoughby
Jan 28, 2014
Gary Willoughby
Jan 28, 2014
bearophile
Jan 28, 2014
Meta
Jan 29, 2014
bearophile
January 28, 2014
Using std.algorithm how to uniq and sort a multidimensional array?

e.g. the uniq function takes a function as a predicate but i'm confused how to handle the multiple dimensions.

    string[][] tags;

    tags = tags.uniq!("a[0][1] == b[1][1]").array;

The above is my attempt and it failed.
January 28, 2014
On Tuesday, 28 January 2014 at 14:46:48 UTC, Gary Willoughby wrote:
> Using std.algorithm how to uniq and sort a multidimensional array?
>
> e.g. the uniq function takes a function as a predicate but i'm confused how to handle the multiple dimensions.
>
>     string[][] tags;
>
>     tags = tags.uniq!("a[0][1] == b[1][1]").array;
>
> The above is my attempt and it failed.

Gah, it was simpler than i thought, of course.

	tags = tags.sort!("a[1] < b[1]").uniq!("a[1] == b[1]").array;
January 28, 2014
Gary Willoughby:

>     string[][] tags;
>
>     tags = tags.uniq!("a[0][1] == b[1][1]").array;

I think the right abstraction for your use case is:

auto tags = tags.flatten.uniq.array;

Where a std.range.flatten should take a range, range of ranges, range of range of ranges, etc, and yield the items scanning them by rows (flatten takes a template argument enumeration to change the scanning pattern: by rows, by columns, bidirectional rows, zig-zag, Hamming curve, Z curve, 2D rectangular blocks).

Probably flatten should have a compile-time argument to tell it what a iterable range means. And an optional run-time argument "maxDepth".

Ideally flatten should yield references of the items, so you can increase all matrix items by 1 with code like:

int[][][] matrix = ...;
foreach (ref item; mat.flatten)
    item++;

Bye,
bearophile
January 28, 2014
On Tuesday, 28 January 2014 at 15:07:26 UTC, bearophile wrote:
> Gary Willoughby:
>
>>    string[][] tags;
>>
>>    tags = tags.uniq!("a[0][1] == b[1][1]").array;
>
> I think the right abstraction for your use case is:
>
> auto tags = tags.flatten.uniq.array;

auto tags = tags.flatMap!uniq.array ?
January 29, 2014
Meta:

> auto tags = tags.flatMap!uniq.array ?

That's another solution. In Phobos a flatMap can be useful (just as a zip overload that accepts a function to apply on the pairs, named zipWith in haskell: http://zvon.org/other/haskell/Outputprelude/zipWith_f.html ).

Bye,
bearophile