Re: Idiomatic adjacent_difference
On Friday, 16 October 2015 at 15:02:54 UTC, anonymous wrote: By the way, what's the point of `dropOne` over `drop(1)`? It's not shorter. Does it do anything subtly different? I also find it strange.
Re: Idiomatic adjacent_difference
On Friday, 16 October 2015 at 11:48:19 UTC, Edwin van Leeuwen wrote: zip(r, r[1..$]).map!((t) => t[1]-t[0]); And for InputRanges (not requiring random-access): zip(r, r.dropOne).map!((t) => t[1]-t[0]);
Re: Idiomatic adjacent_difference
On Friday, 16 October 2015 at 11:38:35 UTC, John Colvin wrote: import std.range, std.algorithm; auto slidingWindow(R)(R r, size_t n) if(isForwardRange!R) { //you could definitely do this with less overhead return roundRobin(r.chunks(n), r.save.drop(1).chunks(n)) .filter!(p => p.length == n); } auto adjacentDiff(R)(R r) { return r.slidingWindow(2).map!"a[1] - a[0]"; } Nice ! I wanted to use lockstep(r, r.dropOne) but it doesn't return a Range :-/ It has to be used in a foreach.
Idiomatic adjacent_difference
Is there an idiomatic way to do: int[] numbers = [0, 1, 2, 3]; assert(adjacent_diff(numbers) == [1, 1, 1]); I can't find something useful in the std library.
Re: Idiomatic adjacent_difference
On Friday, 16 October 2015 at 11:11:28 UTC, Guillaume Chatelet wrote: Is there an idiomatic way to do: int[] numbers = [0, 1, 2, 3]; assert(adjacent_diff(numbers) == [1, 1, 1]); I can't find something useful in the std library. import std.range, std.algorithm; auto slidingWindow(R)(R r, size_t n) if(isForwardRange!R) { //you could definitely do this with less overhead return roundRobin(r.chunks(n), r.save.drop(1).chunks(n)) .filter!(p => p.length == n); } auto adjacentDiff(R)(R r) { return r.slidingWindow(2).map!"a[1] - a[0]"; } unittest { import std.stdio; int[] numbers = [0, 1, 2, 3]; writeln(numbers.slidingWindow(2)); writeln(adjacentDiff(numbers)); assert(adjacentDiff(numbers).equal([1, 1, 1])); }
Re: Idiomatic adjacent_difference
On Friday, 16 October 2015 at 11:43:16 UTC, Guillaume Chatelet wrote: On Friday, 16 October 2015 at 11:38:35 UTC, John Colvin wrote: Nice ! I wanted to use lockstep(r, r.dropOne) but it doesn't return a Range :-/ It has to be used in a foreach. Instead of lockstep you can always use zip (which is the same but returns a range) zip(r, r[1..$]).map!((t) => t[1]-t[0]);
Re: Idiomatic adjacent_difference
On Friday, 16 October 2015 at 12:03:56 UTC, Per Nordlöw wrote: On Friday, 16 October 2015 at 11:48:19 UTC, Edwin van Leeuwen wrote: zip(r, r[1..$]).map!((t) => t[1]-t[0]); And for InputRanges (not requiring random-access): zip(r, r.dropOne).map!((t) => t[1]-t[0]); That's neat. Thx guys :)
Re: Idiomatic adjacent_difference
On Friday, 16 October 2015 at 12:03:56 UTC, Per Nordlöw wrote: On Friday, 16 October 2015 at 11:48:19 UTC, Edwin van Leeuwen wrote: zip(r, r[1..$]).map!((t) => t[1]-t[0]); And for InputRanges (not requiring random-access): zip(r, r.dropOne).map!((t) => t[1]-t[0]); We should have a good implementation of slidingWindow in std.range, it's a useful iteration pattern (although it does sometimes encourage inefficient algorithms).
Re: Idiomatic adjacent_difference
On Friday, October 16, 2015 02:03 PM, Per Nordlöw wrote: > zip(r, r.dropOne).map!((t) => t[1]-t[0]); You should r.save one or both of those. The dropOne may affect both instances if you don't .save. By the way, what's the point of `dropOne` over `drop(1)`? It's not shorter. Does it do anything subtly different?
Re: Idiomatic adjacent_difference
On Friday, 16 October 2015 at 15:02:54 UTC, anonymous wrote: On Friday, October 16, 2015 02:03 PM, Per Nordlöw wrote: zip(r, r.dropOne).map!((t) => t[1]-t[0]); You should r.save one or both of those. The dropOne may affect both instances if you don't .save. By the way, what's the point of `dropOne` over `drop(1)`? It's not shorter. Does it do anything subtly different? The only difference is that dropOne calls popFront and drop calls popFrontN.