www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - drop* and take* only for specific element values

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
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.
Aug 13 2014
parent reply "Meta" <jared771 gmail.com> writes:
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?
Aug 13 2014
next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
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
Aug 13 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
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/a gorithm.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/ lgorithm.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/ lgorithm.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/ lgorithm.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/a gorithm.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?
Aug 13 2014
next sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
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]; }
Aug 13 2014
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
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
Aug 13 2014
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
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"); }
Aug 14 2014
parent "monarch_dodra" <monarchdodra gmail.com> writes:
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.
Aug 16 2014
prev sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
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
Aug 13 2014