There is only a somewhat dubious benefit to the
if (index < fromIndex) check: if true, the
value = var comparison is avoided. Comparisons of very long strings can be costly, so there may be some specific cases where it helps. However, for the check to be useful, it must take less time than it saves. If the caller doesn't provide a fromIndex greater than 1 - or if the array contains only numbers or objects - no time will be saved by the check, so it will only hurt performance. That might also be true for short string comparisons.
If you remove that redundant part, the function is basically the same as jNizM's but without the IsObject and Length checks.
The Length check has the effect of avoiding the construction of an enumerator object when the function is given an empty array, so the function might perform better for such arrays. However, since the check itself has a cost, it will perform worse for the most common cases, where the array is not empty. In other words, it's not useful.
If you pass a non-object value to the for-loop, it will just do nothing, like
Loop 0. However,
haystack.Length() would throw an exception in v2 if haystack is not an object, so the IsObject check serves the purpose of avoiding that. Otherwise, it's pretty useless.
If you wanted to differentiate between "value not found" and "haystack not valid", it would be more efficient to do so
after the for-loop:
Code: Select all
HasVal(haystack, needle) {
for index, value in haystack
if (value = needle)
return index
if !IsObject(haystack)
throw Exception("Bad haystack!", -1, haystack)
return 0
}
The Length check has another effect: inconsistent behaviour when the caller passes an associative array. For example:
Code: Select all
MsgBox % HasVal({key: "X"}, "X") ; 0
MsgBox % HasVal({key: "X", 1: 0}, "X") ; key
Without the Length check, the function would work just fine with associative arrays.
stealzy wrote:I rewrite it without slow .MaxIndex() method.
(I may be misinterpreting you.) MaxIndex is not the slow part - you're only calling it once per function call. The slow part is most likely looking up the array index on every iteration - i.e.
Arr[A_Index + fromIndex - 1]. Using an enumerator avoids these lookups (but the enumerator itself has overhead, so in
some cases it's not the best choice).