## digitalmars.D.learn - Splitting a sequence using a binary predicate on adjacent elements

=?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
```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

[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
=?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
```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
jmh530 <john.michael.hall gmail.com> writes:
```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:
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`?

Would probably need to use findAdjacent to get it to work

```
Oct 17 2017
Andrea Fontana <nospam example.com> writes:
```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

[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
Andrea Fontana <nospam example.com> writes:
```More phobos-ized version:

https://run.dlang.io/is/iwgeAl

Andrea
```
Oct 17 2017
=?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
```On Tuesday, 17 October 2017 at 15:47:25 UTC, Andrea Fontana wrote:
More phobos-ized version:

https://run.dlang.io/is/iwgeAl

Thanks!
```
Oct 17 2017
=?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
```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
```
Oct 17 2017
Andrea Fontana <nospam example.com> writes:
```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:
auto splitBy(alias F, R)(R range)

Because of lazyness shouldn't it be named something with

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.

Andrea
```
Oct 18 2017
=?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
```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
Andrea Fontana <nospam example.com> writes:
```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:
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.

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.
```
Oct 18 2017