Hi,
I'm trying to test a fruitless foreach, and I'm surprised to see that the result is not just null or empty.- can you tell me why this code returns 20 null lines please (please see the attached file) ? I was expecting an empty list-
- In this case, how to assert that the result is fruitless ?
a!localVariables( /* Get a list of 20 Vehicles */ local!vehicles: a!flatten(rule!CJT2_GetVehiclesWithFilters( id: null ).data), /* The id = 550 does not exist in the Vehicles so we'll not find it */ local!oneVehicle: a!forEach( items: local!vehicles, expression: if(tointeger(fv!item.id)=550, fv!item, {} ) ), local!oneVehicle )
The object of this post, is not to replace foreach by another function (like index or reject) but to understand how works the foreach.
Regards
Discussion posts and replies are publicly visible
The nature of foreach() is to return a value for each item. This is exactly the reason why I strongly suggest to not use it for filtering.
that is the other topic: Why not using the queryfilter for the id in the query ? its the way better approach to filter.
Ok I understand the point, thank you Stefan
As I have mentionned Richard, I was not expecting to go further in this other topic.
My question was only about the "foreach" aspect (maybe I should provide a static set of data for my example ;-) )
I differ on this - other than the single corner case we see here where it returns an empty item for each iteration when all iterations are empty, having it spit back empty sets works just fine - and as long as you anticipate this behavior (which is funny tbh), a!forEach filtering can create much more coherent code than using primitive functions/looping.
Mike Schmitt said:a!forEach filtering can create much more coherent code than using primitive functions/looping.
For me what's missing is the ability in an if() or equivalent is to execute a NOP (No Operation) - that is, to opt to choose to output nothing at all. There have been many times where I have processed a list and then had to post-process the list to remove null values from it.
I recently created a helper expression for filter(). It takes a list of queryFilters and applies them to the list items returning true if all match. That makes is an almost universal filter.
Stewart Burchell said:There have been many times where I have processed a list and then had to post-process the list to remove null values from it.
As long as you're talking about a simple a!forEach() loop, simply configuring it to return empty sets for "no data" result iterations (and wrapping the whole thing in a!flatten() when there's a possibility of all items satisfying this null case) takes care of this very quickly though.
Yup, I get that's an option. In the same way I can wrap the whole thing with fn!reject() - it just seems to me an unnecessary extra thing to have toi do.
It seems like a weird behavior for a!forEach to exhibit, i'll grant. I assume at this point they don't want to just up and change its behavior though - although I'd be up for an upgraded version at some point, preferably with extra functionality/options as you note.