digitalmars.D.learn - Splitting a sequence using a binary predicate on adjacent elements
- =?UTF-8?B?Tm9yZGzDtnc=?= (8/8) Oct 17 2017 I can't find any algorithm/range in Phobos that can be used to
- =?UTF-8?B?Tm9yZGzDtnc=?= (4/5) Oct 17 2017 If not, what should we call it?...yet another overload of
- jmh530 (4/9) Oct 17 2017 Would probably need to use findAdjacent to get it to work
- Andrea Fontana (24/32) Oct 17 2017 Try this:
- Andrea Fontana (3/3) Oct 17 2017 More phobos-ized version:
- =?UTF-8?B?Tm9yZGzDtnc=?= (2/4) Oct 17 2017 Thanks!
- =?UTF-8?B?Tm9yZGzDtnc=?= (3/4) Oct 17 2017 Because of lazyness shouldn't it be named something with
- Andrea Fontana (12/17) Oct 18 2017 Yes but I think it is something more similar to chunkBy, but
- =?UTF-8?B?Tm9yZGzDtnc=?= (6/8) Oct 18 2017 What's the motivation behind this limitation?
- Andrea Fontana (18/26) Oct 18 2017 Probably it's an implementation problem. On source code you read:
I can't find any algorithm/range in Phobos that can be used to split (eagerly or lazily) a sequence using a binary predicate on adjacent elements as follows [1,2,3,5,10,11,12,13,20,21,100].splitBy!"a + 1 != b"() should evaluate to [[1,2,3], [5], [10,11,12,13], [20,21], [100]] . Is there one?
Oct 17 2017
On Tuesday, 17 October 2017 at 13:09:18 UTC, Nordlöw wrote:Is there one?If not, what should we call it?...yet another overload of `splitter()` with a binary predicate and only a single parameter `Range input`?
Oct 17 2017
On Tuesday, 17 October 2017 at 13:25:01 UTC, Nordlöw wrote:On Tuesday, 17 October 2017 at 13:09:18 UTC, Nordlöw wrote:Would probably need to use findAdjacent to get it to work https://dlang.org/phobos/std_algorithm_searching.html#findAdjacent So splitterAdjacent?Is there one?If not, what should we call it?...yet another overload of `splitter()` with a binary predicate and only a single parameter `Range input`?
Oct 17 2017
On Tuesday, 17 October 2017 at 13:09:18 UTC, Nordlöw wrote:I can't find any algorithm/range in Phobos that can be used to split (eagerly or lazily) a sequence using a binary predicate on adjacent elements as follows [1,2,3,5,10,11,12,13,20,21,100].splitBy!"a + 1 != b"() should evaluate to [[1,2,3], [5], [10,11,12,13], [20,21], [100]] . Is there one?Try this: import std.range; import std.algorithm; import std.stdio; import std.typecons; auto splitBy(alias F, R)(R range) { auto tmp = range .map!(x => tuple(x, 0)) .cumulativeFold!((a,b) => tuple(b[0], (!F(a[0],b[0]))?a[1]:a[1]+1)) .chunkBy!((a,b) => a[1] == b[1]) .map!(x => x.map!(y => y[0])); return tmp; } void main() { [1,2,3,5,10,11,12,13,20,21,100].splitBy!((a,b) => a+1 != b)().writeln; } Andrea
Oct 17 2017
More phobos-ized version: https://run.dlang.io/is/iwgeAl Andrea
Oct 17 2017
On Tuesday, 17 October 2017 at 15:47:25 UTC, Andrea Fontana wrote:More phobos-ized version: https://run.dlang.io/is/iwgeAlThanks!
Oct 17 2017
On Tuesday, 17 October 2017 at 14:15:02 UTC, Andrea Fontana wrote:auto splitBy(alias F, R)(R range)Because of lazyness shouldn't it be named something with splitter, say splitterBy, instead?
Oct 17 2017
On Wednesday, 18 October 2017 at 06:45:37 UTC, Nordlöw wrote:On Tuesday, 17 October 2017 at 14:15:02 UTC, Andrea Fontana wrote:Yes but I think it is something more similar to chunkBy, but chunkBy says that "predicate must be an equivalence relation, that is, it must be reflexive (pred(x,x) is always true), symmetric (pred(x,y) == pred(y,x)), and transitive (pred(x,y) && pred(y,z) implies pred(x,z)). If this is not the case, the range returned by chunkBy may assert at runtime or behave erratically." If you try to use your data with chunkBy!"a != b+1", it does not work, as expected. I think that my implementation could superseed the current one, since it seems to work in a more generic way. Andreaauto splitBy(alias F, R)(R range)Because of lazyness shouldn't it be named something with splitter, say splitterBy, instead?
Oct 18 2017
On Wednesday, 18 October 2017 at 07:01:19 UTC, Andrea Fontana wrote:If you try to use your data with chunkBy!"a != b+1", it does not work, as expected.What's the motivation behind this limitation? Without it chunkBy!"a + 1 == b" is exactly what I want.
Oct 18 2017
On Wednesday, 18 October 2017 at 07:26:20 UTC, Nordlöw wrote:On Wednesday, 18 October 2017 at 07:01:19 UTC, Andrea Fontana wrote:Probably it's an implementation problem. On source code you read: // Issue 13595 version(none) // This requires support for non-equivalence relations system unittest { import std.algorithm.comparison : equal; auto r = [1, 2, 3, 4, 5, 6, 7, 8, 9].chunkBy!((x, y) => ((x*y) % 3) == 0); assert(r.equal!equal([ [1], [2, 3, 4], [5, 6, 7], [8, 9] ])); } And other.If you try to use your data with chunkBy!"a != b+1", it does not work, as expected.What's the motivation behind this limitation? Without it chunkBy!"a + 1 == b" is exactly what I want.
Oct 18 2017