ForEach

Started by JTaylor, July 19, 2025, 07:35:12 AM

Previous topic - Next topic

JTaylor

Given the following, if ArrInfo() returns 0, which I interpret to be a valid array with zero elements, shouldn't Foreach just move on without an error?  That is, not show Message() since there are no i's in arr but not give an error?

Jim

arr = obj.GetLinksByText("ChargeWorx", @TRUE)
message("ARR",ArrInfo(arr,1))
ForEach i in arr
  Message("GetImagesBySource-Items",i.GetAttribute("href"))
Next

td

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

; When using a WIL array
Empty = ArrDimension(0)
foreach i in Empty
   Message("Does not dislay and the foreach does not error", i)
next

; When using variants
Empty = ArrDimension(0)
saEmpty = ObjectType('array', Empty)
foreach i in saEmpty
   Message("This errors on the foreach line", i)
next
exit
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

kdmoyers

What's the smoothest way to just instantly convert a variant array into a wil array?  Like is there a MakeIntoWilArray() function?

I've been using something like

arr = obj.GetLinksByText("ChargeWorx", @TRUE)    ; get a variant array
ArrayRedim(arr, arrinfo(arr,1), arrinfo(arr,2))  ; convert to wil array

Which is wordy, but seems to get the job done.
The mind is everything; What you think, you become.

JTaylor

Now that you mention it I remember having to do something like that with ADO.GetRows().

Any chance ForEach could be tweaked to handle such things?


Jim

JTaylor

Assuming C#, is there an array type it would return that would act like the WilArray?

Jim

Quote from: td on July 19, 2025, 02:17:21 PMNope.


td

Empty = ArrDimension(0)
saEmpty = ObjectType('array', Empty)
iMax = ArrInfo(saEmpty, 1)-1
for i = 0 to iMax
   Message("Does not dislay ", saEmpty[i])
next
exit
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

It might be possible to make Foreach statements skip safearrays without elements but it is trickier than it appears. It will be looked into.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

spl

Quote from: td on July 21, 2025, 09:56:43 AM
Empty = ArrDimension(0)
saEmpty = ObjectType('array', Empty)
iMax = ArrInfo(saEmpty, 1)-1
for i = 0 to iMax
   Message("Does not dislay ", saEmpty[i])
next
exit

Nice. Proof of concept

Empty = ArrDimension(0)
saEmpty = ObjectType('array', Empty)
iMax = ArrInfo(saEmpty, 1)-1
msgs=0
for i = 0 to iMax
   Message("Does not display ", saEmpty[i])
   msgs +=1
next
Message("# of Messages for empty array", msgs)
exit

Jim; appreciate more context on the focus. Assuming a Wil array is empty and you can validate, no need for a for loop. Now, if a returned .net array is empty, then no way to make the same determination with arrinfo(arr,1). Right? Easy to check with my StdOut function for empty PS/.net array  $array = @(), then just check it's ObjectType().
Stan - formerly stanl [ex-Pundit]

JTaylor

Yeah but you know I am really lazy and would just like for it to work consistently :-)  I'll probably just do the following for now. Appreciate the idea though.  Will add that info to my toolbox.

Jim

arr = obj.GetLinksByText("ChargeWorx", @TRUE)
ArrayRedim(arr, arrinfo(arr,1), arrinfo(arr,2))
ForEach i in arr
  Message("GetImagesBySource-Items",i.GetAttribute("href"))
Next

spl

But now you got me all curious.  Simple PS you could run, will return 0 indicating array is empty
$arr = @()
$arr.length

Now in WB with an array object, seems you no can do with .length property but it errors
Empty = ArrDimension(0)
saEmpty = ObjectType('array', Empty)
Message(arrinfo("Empty"), saEmpty.Length)
exit

Error 3068 Illegal Delimiter Found.

Not sure picking on foreach as a construct is important to determining when is an array an array.
Stan - formerly stanl [ex-Pundit]

JTaylor

Not sure I understand the last part so my reply may be off-track. 

I wasn't using ForEach to determine if it was an array.  In this context I know it will always be an array.  I just want to have it move on past the ForEach if the array was empty like it does for a native Array, which in my mind makes sense as it would be completing the logic of ForEach.  I could check the count and then using an IF statement take appropriate action but going with Redim makes it so I don't have to do that with the added bonus that if I do something later with that array it is already converted and i won't have to worry about compatibility. 

Jim

spl

Stan - formerly stanl [ex-Pundit]

td

The reason an empty variant array is treated as an error is that COM Automation and .BurgerFlipper signal that it is a soft error. That is, the type for an empty variant array is sometimes "ARRAY|ERROR" as detected by the ObjectTypeGet function. Also, remember that the implementation for accessing variant array elements predates the ForEach statement.

So to maintain consistency, ForEach considers empty variant arrays an error condition. That said, the ForEach statement will break one consistency for another and treat variant arrays like WIL arrays in the next release. This is because using ForEach is a common way to access variant array elements
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor

Excellent.  Thank you.

Jim

SMF spam blocked by CleanTalk