Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Studio Chat / [SOLVED] Please show me how to use Array.find() correctly

Author
Message
marvin944
10
Years of Service
User Offline
Joined: 27th Aug 2013
Location:
Posted: 10th Dec 2019 10:55
I have an array of a type, but it seems that .find() does not look at the first variable of that type (as stated in manual). It returns an index a bit further in the array.

I tried sorting it, but that didn't help

Is this a bug?
Dutch

The author of this post has marked a post as an answer.

Go to answer

Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 10th Dec 2019 11:06
Do you have an example of code where it isnt working?

I have used .find() quite a lot and have only ever had issues where the array wasnt sorted first.
marvin944
10
Years of Service
User Offline
Joined: 27th Aug 2013
Location:
Posted: 10th Dec 2019 12:31
Well, the code is quite big, but I'll try:

type BMtype
_nr as integer
_scene as string
_command as string
_value as string
_x as string
_y as string
_w as string
_h as string
_z as string
_position as string
_scale as string
_min as string
_max as string
_id as string
_file1 as string
_file2 as string
_file3 as string
_group as string
_goto as string
_goto_condition as string
_speed as string
_onlyif as string
_time as string
_action as string
_fps as string
_attributes as string
_rotation as string
_rotationspeed as string
_name as string
_alpha as string
_color as string
_font as string
_from as string
_to as string
_status as string
_update as string
_url as string
endtype

Bm as BMtype[0]

adding to that array is done by

bm.length=bm.length+1

and then filling the vars.

_nr is filled with ascending numbers, some of which are the same, like 1,1,1,1,2,2,2,3,3,3,3,3,4,5,6,6,6 etc.

I then do a Bm.sort

When i do a index=bm.find(1) I get an answer like 7... It should be 1

When I loop through to find the first 1, that works just fine...


Dutch
Qugurun
Valued Member
9
Years of Service
User Offline
Joined: 8th Dec 2014
Playing: AppGameKit
Posted: 10th Dec 2019 13:04


Attachments

Login to view attachments
Qugurun
Valued Member
9
Years of Service
User Offline
Joined: 8th Dec 2014
Playing: AppGameKit
Posted: 10th Dec 2019 13:15
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 10th Dec 2019 13:16 Edited at: 10th Dec 2019 13:31
@marvin

Unfortunately, you havent really posted any code that will run...just a description of what your are trying to do. Its near impossible to find the bug in your code without any code to work with im afraid.

It sounds as though you are not sorting correctly or are inserting new items into a position that are not sorted...it could be something else (indexing, a simple mistype etc....).

Qugurun has given you a really great example of it sorting and searching correctly. Awesome reply that^^^

Here's another really simple example where you can insert or remove items and the array remains sorted and the searches work fine:



my guess is that your doing something wrong but its difficult to say what without an example that is failing.
marvin944
10
Years of Service
User Offline
Joined: 27th Aug 2013
Location:
Posted: 10th Dec 2019 14:03
My code is quite big and all over the place so not easy to cut/paste, so i wrote a general idea. It definitely should work, I know, so yes, there might be a very silly bug in my code, but until now, i've followed the rules. Will start a deeper search. Now at least I'm sure it's not a bug in AGKS. Thanks for the great replies!
Dutch
marvin944
10
Years of Service
User Offline
Joined: 27th Aug 2013
Location:
Posted: 10th Dec 2019 14:36 Edited at: 10th Dec 2019 14:44
Ok, another test:
After filling BM (actually, _nr is always in ascending order, so no sorting should be needed) I do this:

BM.sort()
for i=1 to bm.length
log(str(i) + " " + str(bm[i]._nr))
next
log("Found 1 at: " + str(bm.find(1)))
test$ = BM.toJson()
BM.save( "raw:c:\bmml\BM.json" )

Output log:

Log:1 1
Log:2 1
Log:3 1
Log:4 1
Log:5 1
Log:6 1
Log:7 1
Log:8 1
Log:9 1
Log:10 1
Log:11 1
Log:12 1
Log:13 1
Log:14 2
Log:15 2
Log:16 2
Log:17 3
Log:18 3
Log:19 3
Log:20 3
Log:Found 1 at: 10

The JSON looks like this:

{
"nr": 3,
"scene": "20",
"command": "pause",
"value": "",
"x": "",
"y": "",
"w": "",
"h": "",
"z": "",
"position": "",
etc...

All in good order. Now tell me why find() gives me the wrong index...

Also: Json removes the _underscore_
Dutch
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 10th Dec 2019 14:46 Edited at: 10th Dec 2019 15:03
This post has been marked by the post author as the answer.
The JSON removes the underscore intentionally so that we can used reserved keywords like "type" as a variable inside a type (Ie...._type)

I've just now clicked why is actually happening ! (I feel really stupid)....

Its not actually a bug... but is to do with binary search algorithm ....In a binary search, as soon as correct match is found it returns the index of the first correct match it finds....that isn't necessarily the lowest index!

So the .find() will only find the lowest index if all the values in your array are unique....otherwise it is not guaranteed to find the lowest index....just the first one that actually matches....


In other words......1,1,1,2,2,2,3,3,3

find(2) could return position 4,5 or 6 as they are all technically correct - it just depends on which one the binary search gets to first.

You would have to use your own function if you always want the lowest index and count upwards until you find a match..... Phew!
marvin944
10
Years of Service
User Offline
Joined: 27th Aug 2013
Location:
Posted: 10th Dec 2019 14:48 Edited at: 10th Dec 2019 14:56
Well, that explains a lot indeed. Hmm, so back to looping through an array (which seems silly)... [probably not a lot slower than if find() did it. Although I would like that routine check out the boundaries of the first an last occurence...

BM.findfirst(3)
BM.findlast("hello")

Will do both in my new version. Do a find and then go backwards finding the first one.

obj=BM.find(cs)
for obj = obj-1 to 0 step-1
if bm[obj]._nr <> cs
inc obj
exit
endif
next obj
Dutch
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 10th Dec 2019 14:52 Edited at: 10th Dec 2019 14:55
Yeah.... you could always use find() then a while loop to check if there are lower indexes that also share the value starting at the find position

Everyday is a learning day for me


EDIT:

i forgot to mention something that is almost completely not documented with the sort command

If you are going to sort by strings the .sort(1) sorts alphabetically (non capitals dependant) and sort (0) sorts by ascii value....
Took me an age to find that little caveat^^^
marvin944
10
Years of Service
User Offline
Joined: 27th Aug 2013
Location:
Posted: 10th Dec 2019 14:54
I foresee an addendum/warning in the manual
Dutch
marvin944
10
Years of Service
User Offline
Joined: 27th Aug 2013
Location:
Posted: 10th Dec 2019 14:58
QUGURUN was close to finding the 'error' with his 29's
Dutch
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 10th Dec 2019 15:10
I must admit....some additional clarification/warnings in the array commands would be good, so it was more obvious what the functions can and cant do.

Even the code that I posted has that issue of not giving the lowest possible index if you add enough enough items to the array.

The docs dont state that a binary search is used (as far as i can see anyway) and the lowest index isnt returned necessarily so its not totally obvious. (i do feel foolish though)
Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 11th Dec 2019 12:00 Edited at: 11th Dec 2019 12:02
Where was it documented scraggle?? The argument in the sort command (1 or 0) wasnt in any of the guides or commands that i could find - maybe I missed it?
Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 11th Dec 2019 12:19 Edited at: 11th Dec 2019 12:21
lol... I know you didnt .....it was a facetious remark by me as I have a terrible sense of humour. I wanted to say its undocumented but I couldnt as technically it is mentioned in just one place....

I had to put ALMOST completely not documented as there really isnt ANY documentation for that feature other than.....in the "whats new" section where it was mentioned just once refering to the 12.12.2017 release.

I wanted to say...."that needs documentation!! grr.." but i suppose the whats new section IS documentation??

Login to post a reply

Server time is: 2024-04-18 07:54:10
Your offset time is: 2024-04-18 07:54:10