digitalmars.D - enumerate, and some improvements
- bearophile (92/92) Sep 24 2014 Jakob Ovrum and others have added an enumerate() function to
- bearophile (4/20) Sep 27 2014 This part of ER 8715 is coming from quickfur:
Jakob Ovrum and others have added an enumerate() function to Phobos: https://issues.dlang.org/show_bug.cgi?id=5550 https://github.com/D-Programming-Language/phobos/pull/1866 A problem with enumerate() (present in other ranges too): void main() { import std.stdio, std.range; auto A = [0, 0, 0, 0]; // A trap: the compiler here accepts ref but it's ignored. foreach (immutable i, ref x; A.enumerate) x = i; writeln(A); } Outputs: [0, 0, 0, 0] ------------------ A feature I'd like in Phobos is an optional "key" function for the min/max functions. An example, compared to using "minPos" (https://d.puremagic.com/issues/show_bug.cgi?id=4705 ): void main() { import std.stdio, std.algorithm, std.range; string[] data = ["red", "hello", "yes", "no", "roger", "bud"]; data .minPos!q{ a.walkLength > b.walkLength } .front .writeln; // Proposed: data.reduce!(max!q{ a.walkLength }).writeln; } The optional key function for max/min functions has some advantages: the code is simpler, shorter, and it computes walkLength only once for each string (so it's faster if the key function is nontrivial and gives less surprises if the given range is not pure). ------------------ A range I'd like in Phobos is std.range.pairwise: https://d.puremagic.com/issues/show_bug.cgi?id=6788 It's different from cartesianProduct and zip, it generates just a triangle of pairs: void main() { import std.stdio, std.typecons; auto data = [1, 2, 3, 4]; foreach (tup; data.pairwise) writeln(tup); foreach (i, x1; data) foreach (x2; data[i + 1 .. $]) writeln(tuple(x1, x2)); } It should print: Tuple!(int, int)(1, 2) Tuple!(int, int)(1, 3) Tuple!(int, int)(1, 4) Tuple!(int, int)(2, 3) Tuple!(int, int)(2, 4) Tuple!(int, int)(3, 4) So: foreach (tup; data.pairwise) is similar to: foreach (i, x1; data) foreach (x2; data[i + 1 .. $]) auto tup = tuple(x1, x2) Such nested iteration is a common need. ------------------ I'd like "zip" to optionally accept a function/constructor: https://d.puremagic.com/issues/show_bug.cgi?id=8715 Two usage examples: void main() { import std.range; auto r1 = zip!q{a + b}([1,2,3], [10,20,30]); static struct Vec { int x, y; } auto r2 = zip!Vec([1,2,3], [10,20,30]); } This can be done with zip+map but this is shorter and more efficient. It's similar to the Haskell function zipWith. ------------------ And I'd like map/filter to accept arrays and associative arrays, and not just functions: void main() { import std.algorithm: map; auto keys = [1, 2, 1, 1, 1]; auto a = [0, 10, 20]; auto r1 = map!(k => a[k])(keys); // OK auto r2 = map!a(keys); // Error auto aa = [1: 10, 2: 20]; auto r3 = map!(k => aa[k])(keys); // OK auto r4 = map!aa(keys); // Error } This is a common idiom in Clojure. Arrays and associative arrays can be seen as functions defined by an enumeration of input-outputs. Bye, bearophile
Sep 24 2014
------------------ And I'd like map/filter to accept arrays and associative arrays, and not just functions: void main() { import std.algorithm: map; auto keys = [1, 2, 1, 1, 1]; auto a = [0, 10, 20]; auto r1 = map!(k => a[k])(keys); // OK auto r2 = map!a(keys); // Error auto aa = [1: 10, 2: 20]; auto r3 = map!(k => aa[k])(keys); // OK auto r4 = map!aa(keys); // Error } This is a common idiom in Clojure. Arrays and associative arrays can be seen as functions defined by an enumeration of input-outputs.This part of ER 8715 is coming from quickfur: https://github.com/D-Programming-Language/phobos/pull/2556 Bye, bearophile
Sep 27 2014