Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
August 13, 2014 drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
Are there variants of drop* and take* that only drop element if its equal to a value kind of like strip does? If not I believe they should be added. |
August 13, 2014 Re: drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Wednesday, 13 August 2014 at 12:37:34 UTC, Nordlöw wrote:
> Are there variants of drop* and take* that only drop element if its equal to a value kind of like strip does?
>
> If not I believe they should be added.
No, but it'd probably be useful. Maybe call them dropIf/takeIf, or just add an overload that takes a predicate... I'll look into making a pull request sometime this week. How do you envision these working?
|
August 13, 2014 Re: drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Meta | On Wed, 13 Aug 2014 14:28:29 +0000 Meta via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > On Wednesday, 13 August 2014 at 12:37:34 UTC, Nordlöw wrote: > > Are there variants of drop* and take* that only drop element if its equal to a value kind of like strip does? > > > > If not I believe they should be added. > > No, but it'd probably be useful. Maybe call them dropIf/takeIf, or just add an overload that takes a predicate... I'll look into making a pull request sometime this week. How do you envision these working? They're called find and until. You just have to give them the opposite predicate that you'd give a function called dropIf or takeIf. - Jonathan M Davis |
August 13, 2014 Re: drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
On Wed, 13 Aug 2014 07:45:17 -0700 Jonathan M Davis via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > On Wed, 13 Aug 2014 14:28:29 +0000 > Meta via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> > wrote: > > > On Wednesday, 13 August 2014 at 12:37:34 UTC, Nordlöw wrote: > > > Are there variants of drop* and take* that only drop element if its equal to a value kind of like strip does? > > > > > > If not I believe they should be added. > > > > No, but it'd probably be useful. Maybe call them dropIf/takeIf, or just add an overload that takes a predicate... I'll look into making a pull request sometime this week. How do you envision these working? > > They're called find and until. You just have to give them the opposite predicate that you'd give a function called dropIf or takeIf. I should probably pointed out that we attempted to put dropWhile and takeWhile into Phobos quite some time ago (which would basically be dropIf and takeIf), but Andrei refused to let them in, because all they did was reverse the predicate, so arguments that they should be added based on the fact that find and until take the opposite predicate aren't going to fly. - Jonathan M Davis |
August 13, 2014 Re: drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Wednesday, 13 August 2014 at 14:45:43 UTC, Jonathan M Davis via Digitalmars-d-learn wrote: > They're called find and until. You just have to give them the opposite > predicate that you'd give a function called dropIf or takeIf. Ok, thx. As an exercise I tried auto dropWhile(R, E)(R range, E element) if (isInputRange!R && is(ElementType!R == E)) { import std.algorithm: find; return range.find(a => a != element); } unittest { dln([1, 2, 3].dropWhile(1)); } but it errors as algorithm_ex.d(1452,22): Error: template std.algorithm.find cannot deduce function from argument types !()(int[], void), candidates are: /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/algorithm.d(4261,12): std.algorithm.find(alias pred = "a == b", InputRange, Element)(InputRange haystack, Element needle) if (isInputRange!InputRange && is(typeof(binaryFun!pred(haystack.front, needle)) : bool)) /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/algorithm.d(4541,4): std.algorithm.find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isForwardRange!R1 && isForwardRange!R2 && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool) && !isRandomAccessRange!R1) /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/algorithm.d(4589,4): std.algorithm.find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isRandomAccessRange!R1 && isBidirectionalRange!R2 && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool)) /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/algorithm.d(4661,4): std.algorithm.find(alias pred = "a == b", R1, R2)(R1 haystack, R2 needle) if (isRandomAccessRange!R1 && isForwardRange!R2 && !isBidirectionalRange!R2 && is(typeof(binaryFun!pred(haystack.front, needle.front)) : bool)) /home/per/opt/x86_64-unknown-linux-gnu/dmd/linux/bin64/src/phobos/std/algorithm.d(4887,23): std.algorithm.find(alias pred = "a == b", Range, Ranges...)(Range haystack, Ranges needles) if (Ranges.length > 1 && is(typeof(startsWith!pred(haystack, needles)))) algorithm_ex.d(1452,22): ... (2 more, -v to show) ... algorithm_ex.d(1456,35): Error: template instance algorithm_ex.dropWhile!(int[], int) error instantiating /home/per/Work/justd/msgpack.d(4614,25): Warning: calling msgpack.pack!(false, string).pack without side effects discards return value of type ubyte[], prepend a cast(void) if intentional /home/per/Work/justd/msgpack.d(4614,25): Warning: calling msgpack.pack!(false, string).pack without side effects discards return value of type ubyte[], prepend a cast(void) if intentional What have I done wrong? |
August 13, 2014 Re: drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Wednesday, 13 August 2014 at 21:22:31 UTC, Nordlöw wrote:
> unittest { dln([1, 2, 3].dropWhile(1)); }
should be
unittest { [1, 2, 3].dropWhile(1) == [2, 3]; }
|
August 14, 2014 Re: drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Wednesday, 13 August 2014 at 21:22:31 UTC, Nordlöw wrote:
> return range.find(a => a != element);
> What have I done wrong?
You forgot the !, making the predicate a function argument. It should be
return range.find!(a => a != element);
- Jonathan M Davis
|
August 14, 2014 Re: drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Thursday, 14 August 2014 at 00:56:47 UTC, Jonathan M Davis wrote: > You forgot the !, making the predicate a function argument. It Great! My solution: auto dropWhile(R, E)(R range, E element) if (isInputRange!R && is(ElementType!R == E)) { import std.algorithm: find; return range.find!(a => a != element); } unittest { assert([1, 2, 3].dropWhile(1) == [2, 3]); assert([1, 1, 1, 2, 3].dropWhile(1) == [2, 3]); assert([1, 2, 3].dropWhile(2) == [1, 2, 3]); assert("abc".dropWhile(cast(dchar)'a') == "bc"); } |
August 16, 2014 Re: drop* and take* only for specific element values | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Thursday, 14 August 2014 at 07:30:59 UTC, Nordlöw wrote:
> On Thursday, 14 August 2014 at 00:56:47 UTC, Jonathan M Davis wrote:
>> You forgot the !, making the predicate a function argument. It
>
> Great!
>
> My solution:
Depending on your exact needs, don't forget too about "findSkip" (same as find, but skips found element), as well as filter.
In particular, r.filter!pred.take(N) would give you a (lazy) range consisting of the first 10 elements in r that verify pred. In some cases, "until" could also suit your needs.
Long story short, D range and algorithms are little building blocks. There aren't that many "basic" functions that can't simply be expressed as a combination of already existing blocks.
|
Copyright © 1999-2021 by the D Language Foundation