digitalmars.D.bugs - [Issue 12592] New: std.algorithm.keep?
- via Digitalmars-d-bugs (67/67) Apr 18 2014 https://issues.dlang.org/show_bug.cgi?id=12592
https://issues.dlang.org/show_bug.cgi?id=12592 Issue ID: 12592 Summary: std.algorithm.keep? Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: enhancement Priority: P1 Component: Phobos Assignee: nobody puremagic.com Reporter: bearophile_hugs eml.cc This code uses ranges in a UFCS chain to compute the unique items of immutable data items, and to return an array (if you don't need r to be an array you can omit the last 'array' call): void main() { import std.array: array; import std.algorithm: sort, uniq, map; immutable data = [10, 3, 2, 3, 4, 10]; const int[] r = data.dup.sort().uniq.array; assert(r == [2, 3, 4, 10]); } But that allocates two arrays (beside the data), one in 'dup' and one in 'array'. To avoid that you can write: void main() { import std.algorithm: sort, uniq, copy; immutable data = [10, 3, 2, 3, 4, 10]; auto int[] r = data.dup.sort().release; r.length -= r.uniq.copy(r).length; assert(r == [2, 3, 4, 10]); } But: - This code is not very easy to write correctly the first time (I have had to compile and run it to be sure); - Its semantics and purpose are not as immediately clear for the reader as the first version; - Now r can't be const; - We have lost the nice single UFCS chain, and the code is longer. So a possible solution is to add a new function similar 'uniq' that performs that common operation (I don't know if release is needed here): void main() { import std.array: array; import std.algorithm: sort, uniq, map; immutable data = [10, 3, 2, 3, 4, 10]; const int[] r = data.dup.sort().release.keepUniq; assert(r == [2, 3, 4, 10]); } But that seems to contain a common pattern that perhaps it's worth generalizing, a pattern that is equally usable here too: const int[] r2 = data.dup.sort().filter!(x => x > 3).array; That could become: const int[] r2 = data.dup.sort().release.keepFilter!(x => x > 3); Generalizing it could become: const int[] r2 = data.dup.sort().release.keep!(filter!(x => x > 3)); And applied on the original code: const int[] r = data.dup.sort().release.keep!uniq; Another example: auto data2 = [10, 3, 2, 3, 4, 10]; data2 = data2.remove!(x => x > 3); assert(data2 == [3, 2, 3]); Becomes: data2.keep!(remove!(x => x > 3)); But this is not a good example because in my opinion it's much better to fix remove, see issue 10959 . If you have more usage cases please add them below. --
Apr 18 2014