-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[TODO] strutils.countWhile: counts while a predicate is true, starting from either end #8673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Araq
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll accept this since I happen to know where you want to use it, but I'm not convinced strutils.countWhile is useful enough. strutils is full of stuff that I never use, yet strutils is one of the few modules that is used in every program.
| while last >= 0 and s[last] in chars: dec(last) | ||
| result = substr(s, first, last) | ||
|
|
||
| proc countWhile*(str: string, pred : proc(a:char):bool, prefix = true): int = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: Watch the spacing around your colons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prefix should instead be countdown=false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I think s instead of str is more common in the stdlib.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And I think the signature should be this, there is little you can do in this callback that receives a single char...
proc countWhile*(s: string; x: set[char]; countdown = false): intOr maybe
template countWhileIt*(s: string; e: untyped; countdown = false): int| doAssert countWhile("abc//", a=>a == '/', prefix = false) == 2 | ||
| doAssert countWhile("abcDEF", isLowerAscii) == 3 | ||
|
|
||
| let lenS = len(str) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code looks better without the helper lenS, use s.len instead.
| for i in 0..<lenS: | ||
| if not pred(str[i]): return i | ||
| else: | ||
| for i in 0..<lenS: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a countdown loop here instead.
|
I believe I already explained why I don't think this function should make it into the stdlib. Just to reiterate:
Nim actually already has a |
|
/cc @Araq Please re-open this PR; it's good etiquette in open source to wait for an answer from PR author before closing.
In here https://github.com/nim-lang/Nim/pull/8351/files#r203705914 you mentioned parseutils.parseWhile [1] ; that doesn't work:
Yes, it can be emulated with a for loop; but that's less readable, and tricky to use, especially for the
I'm using it in my projects in a number of places (as well as upcoming PR's), it simplifies code.
I added such examples in top-level msg of this PR
no, filter is completely different: [1] |
Okay, but couldn't you use import parseutils
doAssert(skipUntil("abcDEF", {'A' .. 'Z'}) == 3)
This is not inefficient nor unwieldy:
That is a problem. Reverse the string? :) If that's too much of a performance hit then you can implement "prefix" mode for the |
in other languages
in go, strings can be sliced so they return a slice, but nim strings can't be sliced (with reference semantics) so returning a count is the best thing we can do here