Invalid Index error when index is out of range

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
flyingDman
Posts: 2834
Joined: 29 Sep 2013, 19:01

Invalid Index error when index is out of range

17 Feb 2023, 02:53

This works in V1:

Code: Select all

var := "
(
a,b
d,e,f
h,i
k,l,m
)"

for x,y in strsplit(var,"`n","`r")
	{
	arr := strsplit(y,",")
	msgbox % arr[1] " " arr[2] " " arr[3]
	}
The fact that some lines contain 2 elements rather than 3 is ignored. In V2, using arr[3] will cause an "Invalid index" error (why?). The issue seems to be solved using something like this:

Code: Select all

#Requires AutoHotkey v2.0
var := "
(
a,b
d,e,f
h,i
k,l,m
)"

for x,y in strsplit(var,"`n","`r")
	{
	arr := strsplit(y,",")
	msgbox(arr[1] " " arr[2] " " (!arr.Has(3) ? "" : arr[3]))
	}
But i do not particularly like it. Is there a better way to avoid the error? It makes me wish there was a setting to disable this behavior.
14.3 & 1.3.7
iPhilip
Posts: 827
Joined: 02 Oct 2013, 12:21

Re: Invalid Index error when index is out of range

17 Feb 2023, 03:12

That's how arrays work now. You can solve it by creating extra blank elements as follows:

Code: Select all

	arr := strsplit(y ",,",",")  ; <-
	msgbox(arr[1] " " arr[2] " " arr[3])
Windows 10 Pro (64 bit) - AutoHotkey v2.0+ (Unicode 64-bit)
User avatar
flyingDman
Posts: 2834
Joined: 29 Sep 2013, 19:01

Re: Invalid Index error when index is out of range

17 Feb 2023, 09:45

Thank you @iPhilip . Just like my approach this feels more like a "band-aid" than a real solution and both add time to the loading of a large listview in an application I am migrating from v1 to v2. As a result of the quirky array behavior, the loading times are longer in V2 than in V1... Disappointing at best! Is this new array behavior documented anywhere? Does anyone have a better solution?
14.3 & 1.3.7
User avatar
kczx3
Posts: 1648
Joined: 06 Oct 2015, 21:39

Re: Invalid Index error when index is out of range

17 Feb 2023, 10:28

I don't see how this would impact the loading times. Can you provide an example that exhibits the delay?
Array Object wrote:Attempting to use an array index which is out of bounds (such as zero, or if its absolute value is greater than the Length of the array) is considered an error and will cause an IndexError to be thrown.
User avatar
kczx3
Posts: 1648
Joined: 06 Oct 2015, 21:39

Re: Invalid Index error when index is out of range

17 Feb 2023, 10:31

You can actually just set the length of the array after StrSplit to be 3 and then either use Array.Get with the Default parameter, or assign Array.Default to an empty string.
User avatar
kczx3
Posts: 1648
Joined: 06 Oct 2015, 21:39

Re: Invalid Index error when index is out of range

17 Feb 2023, 10:36

I'd probably go for something like this to create a sort of Model for your row data.

Code: Select all

#Requires AutoHotkey v2.0
var := "
(
a,b
d,e,f
h,i
k,l,m
)"

for x,y in strsplit(var,"`n","`r")
	{
	arr := row(y)
	msgbox(arr[1] " " arr[2] " " arr[3])
	}

class row extends Array {
    __New(str) {
        super.__New(strsplit(str, ",")*)
        this.length := 3
        this.default := ""
    }
}
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Invalid Index error when index is out of range

17 Feb 2023, 10:43

flyingDman wrote:
17 Feb 2023, 02:53
The fact that some lines contain 2 elements rather than 3 is ignored. In V2, using arr[3] will cause an "Invalid index" error (why?).
because StrSplit happens to have produced for u an Array of .Length 2 and accessing the 3rd element would be accessing an element that is out of the array's bounds(which was deemed, with greater likelihood, to have been an error, the developer's or otherwise, so now v2 alerts for it as opposed to v1, which ignores it silently)
Does anyone have a better solution?
many solutions come to mind. depends on what ure after, exactly
  • u could define ur own Array derived type, and override __Item.Get to do the check internally. either using .Has(indexNr) or a try-catch
  • u could override the default Array's __Item.Get to do the same
  • u unconditionally set the resulting array's Length and then:

    Code: Select all

    arrFromStrSplit.Length := 3
    msgbox arrFromStrSplit.Get(3, '') ; get at index or ur-specified-default-value
  • u could just write a function that concatenates the array and returns a string. u know how it goes, im sure: https://www.autohotkey.com/docs/v2/Functions.htm#Variadic
User avatar
flyingDman
Posts: 2834
Joined: 29 Sep 2013, 19:01

Re: Invalid Index error when index is out of range

17 Feb 2023, 15:54

Thank you @kczx3 and @swagfag . All great ideas and all suggestions work but all add to the load time of my LV. It's not a dramatic increase but performance is important here. My LV has 6 columns and ~110,000 rows and will grow... Results of my tests:
If I use MyLV.Add("", arr*) the average loading time of these 110k rows is 1275 ms (slightly better than in V1 at ~ 1400 ms)
If I use @iPhilip approach the time is 1510 ms
If I use my 1st example with !arr.Has(3) the time is 1525 ms
If I use arr.length:=3 and arr.get(3, "") the average time is 1553 ms
If I use try and catch the time is 1715 ms
If I use @kczx3's class, the average time is 1819 ms.
That means that it is a 18 to 43% performance impact.
The reason why I did not initially use a variadic approach in my example is that, although the LV is the center of the app, there are several filters that I (=the user) need to apply and not all the columns are used all the time. Sometime the last column is used, sometime not. I believe I'll change the method that I'll use depending on what filters the user applies so that I'll still get the performance benefit in most cases. This was not a consideration when using V1.
What is more of an "academic" significance is why (as @swagfag puts it) it was deemed necessary to flag this as an error in V2 while V1 ignored it silently, and - more importantly - why is this not something that can be disabled like one of the "warningtypes" in #Warn?
I'll play around with this a bit more but might add inclusion of this as a "warningtype" in the wish list. I use .csv files and listviews quite a bit and the fact that (what I consider) "workarounds" impact the performance of a script, is disappointing.
14.3 & 1.3.7
User avatar
kczx3
Posts: 1648
Joined: 06 Oct 2015, 21:39

Re: Invalid Index error when index is out of range

17 Feb 2023, 16:14

You shouldn't be loading 110,000 rows into a ListView to begin with. That much data should be rendered virtually. That's just the nature of the beast when you start dealing with that kind of data.

Are you at least creating the listview using the Count option with a large number and disabling Redraw during adding of those rows?
User avatar
flyingDman
Posts: 2834
Joined: 29 Sep 2013, 19:01

Re: Invalid Index error when index is out of range

18 Feb 2023, 10:33

A regular Listview can handle that number of rows just fine. That is not the issue. The Count option has virtually no effect in my past tests. -Redraw +Redraw at the contrary is a must as it impacts the speed dramatically.
14.3 & 1.3.7
User avatar
flyingDman
Posts: 2834
Joined: 29 Sep 2013, 19:01

Re: Invalid Index error when index is out of range

18 Feb 2023, 16:28

As I want to be thorough and complete (though it was not the point of my original post), I revisited the Virtual Listview as shown here by @just me : viewtopic.php?f=82&t=98902#p439319. In the example shown there, the speed benefit is about 4% for a 100,000 row listview but increases to 65% * in the case of 1 MM row listview. In my 110,000 row listview the speed improves 8%. It is significant enough for me to use it (as my listview will most likely grow) but I won't be writing home about it... Thanks to @kczx3 for reminding me about it. :thumbup:

* test results are the average of 5 runs
14.3 & 1.3.7
User avatar
kczx3
Posts: 1648
Joined: 06 Oct 2015, 21:39

Re: Invalid Index error when index is out of range

20 Feb 2023, 08:44

For clarity, I don't think the example you linked to by @just me actually demonstrates a virtual ListView. Perhaps you meant to link to the example that @SKAN originally reference as viewtopic.php?p=25486#p25486
CptRootBeard
Posts: 26
Joined: 16 Nov 2020, 14:47
Contact:

Re: Invalid Index error when index is out of range

20 Feb 2023, 10:05

flyingDman wrote:
17 Feb 2023, 15:54
What is more of an "academic" significance is why (as @swagfag puts it) it was deemed necessary to flag this as an error in V2 while V1 ignored it silently, and - more importantly - why is this not something that can be disabled like one of the "warningtypes" in #Warn?
I'll play around with this a bit more but might add inclusion of this as a "warningtype" in the wish list. I use .csv files and listviews quite a bit and the fact that (what I consider) "workarounds" impact the performance of a script, is disappointing.
Error messages like this one have saved me worlds of trouble from a debugging standpoint, especially when writing what are for me more complex OOP applications.
The move toward clearer and more consistent error messaging is a good one, IMO.

I know it's beyond the scope of the question, but is there a reason you're not able to prebuild/load the listview? I think it would be reasonable to create it once and rely on hiding/showing the gui when its needed.
There are cases where this isn't doable, I'm just curious.
User avatar
kczx3
Posts: 1648
Joined: 06 Oct 2015, 21:39

Re: Invalid Index error when index is out of range

20 Feb 2023, 10:22

CptRootBeard wrote:
20 Feb 2023, 10:05
I know it's beyond the scope of the question, but is there a reason you're not able to prebuild/load the listview? I think it would be reasonable to create it once and rely on hiding/showing the gui when its needed.
I'll let the OP reply but I didn't see where it was mentioned that the ListView/GUI is recreated. The OP has filters that can be applied to the ListView meaning that the rows must be deleted and then added back in (only those that match the filter criteria ofc).
CptRootBeard
Posts: 26
Joined: 16 Nov 2020, 14:47
Contact:

Re: Invalid Index error when index is out of range

20 Feb 2023, 10:39

Fair point, perhaps I'm making too many assumptions. Just hoping there may be a different design approach that would alleviate the performance requirements altogether.
User avatar
flyingDman
Posts: 2834
Joined: 29 Sep 2013, 19:01

Re: Invalid Index error when index is out of range

20 Feb 2023, 14:24

All efforts are welcome but these are getting a bit offtopic. Yes, it is all about making the loading times of listviews faster but my focus here and the topic of this thread was: is there a way to disable the error thrown by V2 when using arr[x] when x is out of range?. I suggested a way similar to #warn so that for debugging purposes one still can get the necessary warnings. Are there ways to circumvent the error? The ones suggested all have a negative impact on performance as I have shown above. The referenced post by @kczx3 here does not provide a better solution either as a) it is slower (1774 ms in my test which puts near the bottom of the list) and 2) it affects the column resizing which makes it unusable.
@CptRootBeard There are many tricks to make the user experience faster and smoother like pre-building / preloading the listview and I believe I used them effectively. My current setup loads the gui and immediately preloads the data in an array while reformatting the data in a date column. This takes between 425 ms to 450 ms. The search button is disabled when this happens but this is almost undetectable to the user. When the user clicks the search button the effective loading time of the listview is now down to ~1000 ms. Although the combined time is a little longer than the 1275 ms mentioned earlier, the user perceives it as faster.
14.3 & 1.3.7
CptRootBeard
Posts: 26
Joined: 16 Nov 2020, 14:47
Contact:

Re: Invalid Index error when index is out of range

20 Feb 2023, 15:48

I have a lot of questions about context, and I can't tell if I'm out of my depth or we're just not on the same page.

If you'd like to discuss over PM, I'd gladly offer any help I can. If you'd rather we drop it altogether, that's okay too.
hd0202
Posts: 183
Joined: 04 Oct 2013, 03:07
Location: Germany near Cologne

Re: Invalid Index error when index is out of range

21 Feb 2023, 01:07

add empty field to variable before strsplit

Code: Select all

arr := strsplit(y . ", ",",")
Hubert
Descolada
Posts: 1177
Joined: 23 Dec 2021, 02:30

Re: Invalid Index error when index is out of range

21 Feb 2023, 06:53

My preferred solution would be to preformat the input beforehand. If I know the input will be comma-separated into three columns, then my input wouldn't be

Code: Select all

var := "
(
a,b
d,e,f
h,i
k,l,m
)"
but instead

Code: Select all

var := "
(
a,b,
d,e,f
h,i,
k,l,m
)"
If needed, I would write a small script to fix the input file by appending the necessary amount of commas.

But to "suppress" the index error, you could modify the Array prototype to include the Default property with a pre-set empty string. Untested: Array.Prototype.DefineProp("Default", {get:(*)=>""}) (add to the beginning of your script).
User avatar
flyingDman
Posts: 2834
Joined: 29 Sep 2013, 19:01

Re: Invalid Index error when index is out of range

21 Feb 2023, 13:28

My preferred solution would be to preformat the input beforehand.
. I am getting the data "as-is" with no or little control over how it's structured. There is no opportunity to preformat. In addition, it's not a one time thing. This data changes on regular basis.
If needed, I would write a small script to fix the input file by appending the necessary amount of commas.
Unfortunately that is not much different than what @iPhilip proposed. In other words it's a band-aid and just adds to the execution time of the script.

Array.Prototype.DefineProp("Default", {get:(*)=>""}) gives me the same "index out of range" error. Could you give an example?
Last edited by flyingDman on 24 Feb 2023, 11:31, edited 2 times in total.
14.3 & 1.3.7

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: diegg1739 and 43 guests