Hi Everyone,
Can we exit from a!forEach() loop?
I have a use case , where I need to iterate through the list of users and once the condition met ( checking for the user's organization and weight category), I have to stop iterating through the rest of the items. I need order to achieve this, I have to exit from the loop.
How can I achieve this ?
Apologies for not clarifying the use case earlier.
Use case is given below.
Use Case: There is a list of Boxers. Each boxers belongs to particular organization and weight category. I want to select 2 boxers for the match randomly. 2 boxers must belong to same weight category but different organization.
To achieve this I was trying to loop through list of boxers and fetch 2 boxers belonging to same weight category but different organization. Once I get 2 different boxers, then I wanted to exit the loop, because I got 2 boxers for the match and don't want to loop further. Note: Weight category and organization are not known initially. That also needs to be picked randomly.
Please do let me know if this is still not clear.
Discussion posts and replies are publicly visible
Hi beenav4597,
I don't think that you can exit the for loop on the specific condition.
What can you do that save the null value when the condition is false and save the value on the true condition and outside the loop you can use the reject function for getting the desire output.
a!localVariables( local!test : { 1,2,3,4 }, reject( isnull(_), a!forEach( items: local!test, expression: if( fv!item = 2, fv!item, null() ) ) ) )
You can use wherecontain() function if it fulfills the condition.
https://docs.appian.com/suite/help/22.3/fnc_array_wherecontains.html#:~:text=When%20to%20use%20wherecontains(),field%20in%20that%20CDT%20array.
a!localVariables( local!test : { 1,2,3,4 }, local!index : wherecontains( 2, local!test ), if( a!isNullOrEmpty( local!index ), "", property( local!test, local!index ) ) )
Hopefully it will help.
Not. There is a reason it is called forEach. Depending in your input data there might be other options.
Thanks harshjan for the reply. Does that mean I'll have to iterate through all the items in the list even if the condition has met early?
Thanks @stefan. However, just wanted to know is there any option in Appian to do this? Basically looking for while loop functionality.
You can manually design a looping flow in a process model which exits as soon as a condition is met.
Yes, if you are using for loop, then it will automatically iterate itself.If you can elaborate your use case, then we can find an alternative for that.
This can be achieved with recursion. For an example below, run rule!chris_recur() and it will loop only until it returns a user in org "B" with weight 22 (4th user).
rule!chris_recur()
a!localVariables( local!users: { a!map(user: "Tim", org: "A", weight: 10), a!map(user: "Steve", org: "B", weight: 2), a!map(user: "Sally", org: "A", weight: 14), a!map(user: "Mary", org: "B", weight: 22), a!map(user: "George", org: "C", weight: 5), a!map(user: "Alex", org: "C", weight: 7) }, rule!chris_recur_sub( users: local!users, index: 1 ) )
rule!chris_recur_sub(users,index)
if( and( ri!users[ri!index].org="B", ri!users[ri!index].weight=22 ), ri!users[ri!index], /* Exit - return user */ if( ri!index=count(ri!users), /* Exit - return null/none found */ null, rule!chris_recur_sub( /* Recur to next user */ users: ri!users, index: ri!index+1 ) ) )
Always remember to save your recursive functions before testing them!
a!localVariables( local!users: { a!map(user: "Tim", org: "A", weight: 10), a!map(user: "Steve", org: "B", weight: 2), a!map(user: "Sally", org: "A", weight: 14), a!map(user: "Mary", org: "B", weight: 22), a!map(user: "George", org: "C", weight: 5), a!map(user: "Alex", org: "C", weight: 7) }, index( local!users, intersection( where(local!users.weight = 22), wherecontains("B", local!users.org) ) ) )
It is more fun with recursion, Stefan!!
This is why we need more details on the use case, as you illustrate looping may not even be required.
We should train an AI to do it for us ;-)