Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 17, 2017 Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
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? |
October 17, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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`?
|
October 17, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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 https://dlang.org/phobos/std_algorithm_searching.html#findAdjacent So splitterAdjacent? |
October 17, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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 |
October 17, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | More phobos-ized version: https://run.dlang.io/is/iwgeAl Andrea |
October 18, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | On Tuesday, 17 October 2017 at 15:47:25 UTC, Andrea Fontana wrote:
> More phobos-ized version:
>
> https://run.dlang.io/is/iwgeAl
Thanks!
|
October 18, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | 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?
|
October 18, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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 splitter, say splitterBy, instead?
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
|
October 18, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrea Fontana | 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.
|
October 18, 2017 Re: Splitting a sequence using a binary predicate on adjacent elements | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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.
|
Copyright © 1999-2021 by the D Language Foundation