Jump out of for loop in kotlin - loops

I have this simple loop and condition, but you see below I can't jump out of loop :
rwloop# for (z in rendered_words.size-1 downTo 0 )
{
var css_=rendered_words[z].node.attr("class")
css_?.let {
if (css_=="classzero") {
break#rwloop
}
}
}
But I receive this error in break#rwloop :
break' or 'continue' jumps across a function or a
class boundary

Drop the let lambda since the #rwloop label is not visible inside it and use this:
rwloop# for (z in rendered_words.size-1 downTo 0 )
{
var css_=rendered_words[z].node.attr("class")
if (css_ != null) {
if (css_=="classzero") {
break#rwloop
}
}
}

https://kotlinlang.org/docs/reference/inline-functions.html#non-local-returns
It states that
break and continue are not yet available in inlined lambdas, but we are planning to support them too.
So, you should
Wait until its support comes
Or use local return statement instead,
How?
The lambda is a function itself, so you can return from it, this (if it is the last thing in the for loop like your case) will make the same effect of continue
rwloop# for(z in rendered_words.size-1 downTo 0 ) {
var css_=rendered_words[z].node.attr("class")
css_?.let {
if (css_=="classzero") {
return#let
}
}
}
Kotlin considers the lambda as a boundary (it is not an inner class because it is inlined), so you can't cross it by break nor continue till now.

Related

How can I write an if thats related to a single else, then beneath it an if that is related to a different else?

I want to relate each if statement to the else one below it only. So when the if isn't true the else beneath it is active alone. Then the next if will be run, and the else below that one will be used if its FALSE. How can I do this?
if (.....){
}
else (....){
}
if (.....){
}
else (....){
}
if (.....){
}
else (....){
}
You could use the ternary operator in C.
The syntax is as follows
result = binaryCondition ? valueReturnedIfTrue : valueReturnedIfFalse;
The most straight-forward way of solving this would be to simply exit once you've have entered any if...else block. You can do this with either a return statement inside each conditional, or a break. As long as all of your conditionals are within a loop or outer block, this will bypass your other if...else statements.
For example:
if (a) {
return b + 1
} else {
return b + 2
}
or:
if (a) {
b += 1
break
} else {
b += 2
break
}

Get rid of useless return statement

I am trying to refactor some code and make it easier to read. I noticed that I have some unnecessary return statements at the end of some functions. Here a conceptual example:
func someFunction(a []arr) int {
for _,v := range a {
if v == something {
// will defenitly get here at some point!
return somethingElse
}
}
return -1 // never ever happens!
}
In my opinion the return statement at the end of the function is misleading, because it suggests, that it may be reached at some point. How do I prevent it?
Please note, that I do error handling at some other point, which is why I can be sure, that someFunction will always return somethingElse.
Panic instead of returning fake value at the end of a function:
func someFunction(a []arr) int {
for _,v := range a {
if v == something {
// will defenitly get here at some point!
return somethingElse
}
}
panic("unreachable")
}
This is a common pattern in standard library.

Sum in recursive function

I have a recursive function which I call acc. If a specific condition is fulfilled I call the function again. If not, I want do add a number to the variable a.
In my opinion it does not what it should. Can someone have a look on this:
double acc(v)
{
double a = 0;
for(int q=0; q<v; q++)
{
if(bf(q) < 1)
{
if(ef() == 0)
{
a += cf();
}
else
{
a += df();
}
}
else
{
return a += acc(v);
}
}
return a;
}
I tried to simplify it as good as I can. vis a variable. bf(), cf(), ef() and df() are functions which return an integer value. Now I want that a gets incremented every time a specific condition is fulfilled during the whole recursive process. Does my code what I want? I don't see it at the moment.
Your problem is that a is defined inside the recursive function. If you want to count events inside the recursion, declare a outside of acc().

How to stop an infinite loop in autohotkey using the key you start it with

So i just started using autohotkey and i made this script to spam the trade chat in a game called path of exile, it works pretty well, but i cant get it to stop when i press f1 again, i've tried countles times, but the loop just won't stop
#MaxThreads 2
wintitle=Path of Exile
SetTitleMatchMode,2
DetectHiddenWindows,On
setkeydelay,2500,0
f1::
toggle:=!toggle
Loop
{
if toggle
controlsend,,{enter}{up}{enter}, %wintitle%
else
break
}
return
I think you're better off using SetTimer for this. Loops aren't very easy to work with when it comes to toggles.
i := 0
toggle := 0
F1::
toggle := !toggle
if (toggle) {
SetTimer, Timer_Spam, 10
} else {
SetTImer, Timer_Spam, Off
}
return
Timer_Spam:
TrayTip, Counter, %i%
i++
return
The reason why your loop isn't working is because once you enter the loop the program is stuck there, so to get out you need to work from inside the loop.
You can do this with GetKeyState(), but then you can't use the same key to toggle it on and off, as it'll toggle off as soon as you start it, unless you add Sleep commands in there, in which case it becomes unreliable instead.
You can however use a separate key to stop the loop, shown here.
toggle := 0
i := 0
F1::
toggle := !toggle
if (toggle) {
Loop {
if (GetKeyState("F2", "P")) {
toggle := !toggle
break
}
TrayTip, Counter, %i%
i++
}
}
return
But like I said above, SetTimer achieves the same result in a much more stable way. So I'd go with that.
use MaxThreadsPerHotkey
#MaxThreadsPerHotkey 2
wintitle=Path of Exile
SetTitleMatchMode,2
DetectHiddenWindows,On
setkeydelay,2500,0
return
f1::
toggle:=!toggle
Loop
{
if toggle
controlsend,,{enter}{up}{enter}, %wintitle%
else
break
}
return
This is the easiest approach I was able to do.
Start/stop toggle with key "2", sending "a" with 0.1 second delay.
#MaxThreadsPerHotkey 2
running := false
stop := false
~2::
if(!running) {
running := true
}
else {
stop := true
return
}
loop {
Send {a} ; example sending key "a"
if(stop) {
running := false
stop := false
break
}
Sleep, 100
}
return
My strategy is this,
Use this command:
v::
loop
{
click
if (GetKeyState("b")) {
break
}
}
return
(Its simple AutoClicker)
Working example with Loop command. Yet so simple.
#Persistent
#MaxThreadsPerHotkey 2
toggle := False
f1 UP::
toggle := !toggle
Loop {
If (!toggle) {
break
}
; Spam commands here
}
Return
This code does what you want:
#MaxThreads 2
wintitle=Path of Exile
SetTitleMatchMode,2
DetectHiddenWindows,On
setkeydelay,2500,0
return
F1::
Loop
{
CheckLButton1:
if (GetKeyState("F1"))
{
Goto, CheckLButton1
}
Docode:
controlsend,,{enter}{up}{enter}, %wintitle%
;ToolTip, 1
if (!(GetKeyState("F1")))
{
Goto, Docode
}
CheckLButton2:
if (!(GetKeyState("F1")))
{
return
}
else
{
Goto, CheckLButton2
}
}
return
If you need explanation, look here at my post: http://ahkscript.org/boards/viewtopic.php?f=5&t=4613#p26298

Elegant way for do ... while in groovy

How to do code something like this in groovy?
do {
x.doIt()
} while (!x.isFinished())
Because there is no do ... while syntax in groovy.
No 'do ... while()' syntax as yet.
Due to ambiguity, we've not yet added support for do .. while to Groovy
References:
groovy - dev > do while
Migration From Classic to JSR syntax
Groovy Documentation > Control Structures > Looping
Rosetta Code > Loops/Do-while Groovy
You can roll your own looping that's almost what you want.
Here's an example with loop { code } until { condition }
You can't have a corresponding loop { code } while { condition } because while is a keyword.
But you could call it something else.
Anyway here's some rough and ready code for loop until.
One gotcha is you need to use braces for the until condition to make it a closure.
There may well be other issues with it.
class Looper {
private Closure code
static Looper loop( Closure code ) {
new Looper(code:code)
}
void until( Closure test ) {
code()
while (!test()) {
code()
}
}
}
Usage:
import static Looper.*
int i = 0
loop {
println("Looping : " + i)
i += 1
} until { i == 5 }
So many answers and not a single one without a redundant call, a shame ;)
This is the closest it can get to purely language syntax based do-while in Groovy:
while ({
x.doIt()
!x.isFinished()
}()) continue
The last statement within curly braces (within closure) is evaluated as a loop exit condition.
Instead of continue keyword a semicolon can be used.
Additional nice thing about it, loop can be parametrized (kind of), like:
Closure<Boolean> somethingToDo = { foo ->
foo.doIt()
!foo.isFinished()
}
and then elsewhere:
while (somethingToDo(x)) continue
Formerly I've proposed this answer over here: How do I iterate over all bytes in an inputStream using Groovy, given that it lacks a do-while statement?
Depending on your use case, there are options like this: do .. while() in Groovy with inputStream?
Or you can do:
x.doIt()
while( !x.finished ) { x.doIt() }
Or
while( true ) {
x.doIt()
if( x.finished ) break
}
You can use a condition variable with the regular while loop:
def keepGoing = true
while( keepGoing ){
doSomething()
keepGoing = ... // evaluate the loop condition here
}
Update Groovy 2.6 has been abandoned to concentrate on 3.0.
From Groovy 2.6 on, do-while is supported when enabling the new Parrot Parser, from Groovy 3.0 on this is the default. See release notes:
// classic Java-style do..while loop
def count = 5
def fact = 1
do {
fact *= count--
} while(count > 1)
assert fact == 120
By now, Groovy has support for do/while:
do {
x.doIt()
} while (!x.isFinished())
Or you can implement it in a Groovier way :
def loop(Closure g){
def valueHolder = [:]
g.delegate = valueHolder
g.resolveStrategy = Closure.DELEGATE_FIRST
g()
[until:{Closure w ->
w.delegate = valueHolder
w.resolveStrategy = Closure.DELEGATE_FIRST
while(!w()){
g()
}
}]
}

Resources