Hi,
I have a very simply code and need to make 2 things:
- create a first list that feet a condition
- create another list (exclusion) using the same condition
I would like to see how would you do using a single foreach please ?
a!localVariables( local!lst, local!goodVehicles: a!forEach( items: ri!vehicles, expression: if(and( fv!item.typeid = 1, fv!item.isavailable, not(fv!item.deleted) ), fv!item, {}, ) ), local!badVehicles: a!forEach( items: ri!vehicles, expression: if(and( fv!item.typeid = 1, fv!item.isavailable, not(fv!item.deleted) ), {}, append(local!lst, fv!item), ) ), { good: local!goodVehicles, bad: local!badVehicles } )
Discussion posts and replies are publicly visible
You are aware that append inside a foreach does not work? local!lst will stay the same empty list throughout all iterations.
Wouldn't difference() solve your problem? Means, have the first foreach and build the second list from the difference?
Thank you Stefan, yes Difference() works perfectly well in this example, but it was just an example.
How would you do (if possible) if you had to do it in a single foreach, appendind/removing items in/from lists ? ( I should have take an example where Difderence() is not applicable ;-) )
:-)
I would use the reduce function and a helper expression. I would use the parameter "initial" of reduce as a shared memory which I modify on each iteration.
Did that to implement a block based check sum algorithm for IBAN validation.
Thanks a lot Stefan.
I will take a look a it.
Why are you trying to use append()? You should be constructing a list of badVehicles directly into the local variable you have the a!forEach() call running. "local!lst" seems irrelevant. You're actually already doing it correctly (per what I'd suggest) in the local!goodVehicles configuration - why not do the same thing (just with a reversed filter) in the local!badVehicles declaration?
Mike, my example was incorrect, and yes, the "local!lst" was an error.
I should have wrote this.
/* correction */ local!goodVehicles: a!forEach( items: ri!vehicles, expression: if(and( fv!item.typeid = 1, fv!item.isavailable, not(fv!item.deleted) ), fv!item, {}, ) ), local!badVehicles: a!forEach( items: ri!vehicles, expression: if(and( fv!item.typeid = 1, fv!item.isavailable, not(fv!item.deleted) ), {}, fv!item, ) ), { good: local!goodVehicles, bad: local!badVehicles }
Gotcha; yes this is the approach i'd suggest. Trying to condense this down to one a!forEach loop (and nothing else added) would require enormously more complexity (if even possible).
The one possible alternative I can think of, requiring only one a!forEach() loop, would be to have it create an array of "tags" (i.e. iterate through the vehicles and create a NEW array of strings, each being i.e. "Good", "Bad", "Neutral"), then afterwards, set the local!goodVehicles and local!badVehicles arrays based on indexing into the original array of vehicles based on the indices in the "tag" array i.e. "get every vehicle at a 'good' position", etc. The fallback here being, I'm not sure this is any more efficient, and is certainly at least as complex, as just having your two a!forEach loops.
yes, you're probably right Mike.
Yes, I see what you mean, I tried these solution too, for another case.
Thank you for your help.