Page 1 of 1
Array Question
Posted: Sat Oct 03, 2015 4:22 pm
by CoreySchroeder
Hi there,
I'm trying to create a basic program to better understand array functionality.
I've attached a screenshot of the UI to help you better understand what exactly I'm trying to do here.
I have 2 arrays in which I would like to populate with information.
There are 2 fields where a user can input text - when the "Add" button is clicked, I want push this text into their respective array.
Once the text has been added to the arrays, I want to clear the text in the fields, so the user can add more items to each array.
To test if the arrays are working - the "Show" button, when clicked should then populate the "list" fields at the bottom of the UI with the content of their respective array.
(This is not currently working as expected).
The "Refresh" button, when clicked should "reset" the app - clearing all of the data in all of the fields, and clearing out all of the data in each array - so the user can start over from scratch.
For some reason this is not working as I would like it to.
Here is my card script:
Code: Select all
global varArray1, varArray2
on mouseUp
if the short name of the target is "btnAdd" then
put the text of field "fldArray1Item" into varArray1[last line of the keys of varArray1]
put the text of field "fldArray2Item" into varArray2[last line of the keys of varArray2]
put empty into field "fldArray1Item"
put empty into field "fldArray2Item"
else if the short name of the target is "btnShow" then
put varArray1 into field "fldArray1List"
put varArray2 into field "fldArray2List"
else if the short name of the target is "btnRefresh" then
put empty into field "fldArray1Item"
put empty into field "fldArray2Item"
put empty into field "fldArray1List"
put empty into field "fldArray2List"
put empty into varArray1
put empty into varArray2
end if
end mouseUp
Any help would be greatly appreciated.
Thank you for your time!
Re: Array Question
Posted: Sat Oct 03, 2015 5:38 pm
by SparkOut
You really need to understand more about how in LiveCode arrays are "associative" and can have whatever key you want for each element.
You can make the key a numeric index, but it doesn't have to be. If you do, then you will have to work out your own index management.
I can't stress enough that the array keys are NOT internally ordered by LiveCode, even if you give numeric indexes. Element 1 may be stored between elements 9 and 7 internally. It is not scary, just a different understanding required.
There are quite a few concepts here, so what I have done is rework your code so if you paste this into your card script and step through you should be able to see it work to produce the results you expect, but not at all in the way you thought it would work. This is not how I suggest you go ahead - it is more an explanation of what you have to do to achieve what you were thinking about. Approaching in a different way will become simpler.
Hopefully stepping through with the comments, and checking the variables in the debugger as you go will explain more than me spouting so try this:
Code: Select all
global varArray1, varArray2
on mouseUp
--this is based on the assumption that you are trying to use numeric indexes for the
--array keys, but they don't have to be
if the short name of the target is "btnAdd" then
--find the highest numerical index for the array elements
put the keys of varArray1 into tArr1Keys
put the keys of varArray2 into tArr2Keys
--max works on comma separated lists (or actually arrays, but the keys are not the array)
replace cr with comma in tArr1Keys
replace cr with comma in tArr2Keys
put max (tArr1Keys) + 1 into tNewIndex1
put max (tArr2Keys) + 1 into tNewIndex2
--max() will work on unsorted lists
--BUT it is vital to understand that the keys of an array are NOT sorted
--unless you do this yourself
sort items of tArr1Keys numeric ascending
sort items of tArr2Keys numeric ascending
--the above lines will be needed if you are expecting to identify a particular index due to its order in the list
--this will become more readily noticeable as you experiment and learn about "associative arrays"
--the variables are comma separated lists now so sort by items
--without the change to accommodate max() function, you could sort by lines normally
put the text of field "fldArray1Item" into varArray1[tNewIndex1] -- you can't put it into a line of the keys
--you have to give it a value to become the key for the new element
put the text of field "fldArray2Item" into varArray2[tNewIndex2]
put empty into field "fldArray1Item"
put empty into field "fldArray2Item"
else if the short name of the target is "btnShow" then
--arrays are not "human readable" as one list
--to populate the field as one block (list) you
--first have to combine the array elements
combine varArray1 using return -- just the data
combine varArray2 using return and "_" -- show the keys (with separator) as well
--now the arrays have been combined
--they ARE NO LONGER ARRAYS
put varArray1 into field "fldArray1List"
put varArray2 into field "fldArray2List"
--in order to add more elements without starting again, you will need to
--SPLIT the variables back into arrays, according to how you combined them
split varArray1 by return -- creates numeric index by default
split varArray2 by return and "_" --uses the first value before the separator (number) for the index
else if the short name of the target is "btnRefresh" then
put empty into field "fldArray1Item"
put empty into field "fldArray2Item"
put empty into field "fldArray1List"
put empty into field "fldArray2List"
put empty into varArray1
put empty into varArray2
end if
end mouseUp
Re: Array Question
Posted: Sat Oct 03, 2015 5:51 pm
by dave.kilroy
Hi CoreySchroeder and welcome to the forum.
SparkOut is quite right - arrays are strange (and wonderful) things
Here is another way to get the functionality you wanted - I've split what the buttons do into three different commands in the card's script which the buttons call - and have gone about things in a different way to SparkOut (please note 'extents' work fine in the way I've used them, but would not do so in all circumstances!)
Have fun
Code: Select all
global sArray1, sArray2
command addToArray
if fld "fldArray1" is not empty then
put the number of lines in the keys of sArray1 + 1 into tNum
put fld "fldArray1" into sArray1[tNum]
put empty into fld "fldArray1"
end if
--
if fld "fldArray2" is not empty then
put the number of lines in the keys of sArray2 + 1 into tNum
put fld "fldArray2" into sArray2[tNum]
put empty into fld "fldArray2"
end if
end addToArray
command showArrays
if sArray1 is not empty then
put item 2 of the extents of sArray1 into tMax1
repeat with i = 1 to tMax1
put sArray1[i] & cr after tArrayToString1
end repeat
delete the last char of tArrayToString1
put tArrayToString1 into fld "slfArray1"
end if
--
if sArray2 is not empty then
put item 2 of the extents of sArray2 into tMax2
repeat with i = 1 to tMax2
put sArray2[i] & cr after tArrayToString2
end repeat
delete the last char of tArrayToString2
put tArrayToString2 into fld "slfArray2"
end if
end showArrays
command refreshAll
put empty into fld "fldArray1"
put empty into fld "fldArray2"
put empty into fld "slfArray1"
put empty into fld "slfArray2"
put empty into sArray1
put empty into sArray2
end refreshAll
Re: Array Question
Posted: Sun Oct 04, 2015 3:08 pm
by CoreySchroeder
Thank you both so much for the help!
Coming from other programming languages, LiveCode's use of arrays is a bit different from what I'm used to.
Question about indexing -
It looks like you both are finding the number of keys of the array each time you are adding an item to it.
Could you not simply increment a variable for this instead of searching the total number of keys and adding 1 to it each time?
Something along the lines of:
Code: Select all
local x
put 1 into x
on mouseUp
put something into myArray[x]
add 1 to x
end mouseUp
Also, I took out the sorting function of the array, and every test I did it displayed in the proper order - so I don't quite understand why this step is necessary.
Thanks again for helping a noob out!
Re: Array Question
Posted: Sun Oct 04, 2015 3:14 pm
by CoreySchroeder
Also, do any of you know of a good source to learn more about LiveCode arrays?
I've flipped through the user manual, but the Array section is only like 2 pages long, and really doesn't give the overview I was hoping for.
I can copy and paste code all day long and make it work, but I'd really like to understand how and why its working.
I appreciate your help!
Re: Array Question
Posted: Sun Oct 04, 2015 3:16 pm
by dave.kilroy
Hi - try this link (10 lovely lessons on LiveCode arrays)
Re: Array Question
Posted: Sun Oct 04, 2015 3:20 pm
by CoreySchroeder
Hey Dave - your link didn't work, sir.
I appreciate the reply, however!
Re: Array Question
Posted: Sun Oct 04, 2015 4:15 pm
by dave.kilroy
Re: Array Question
Posted: Sun Oct 04, 2015 4:35 pm
by CoreySchroeder
Dave - you're the best.
Re: Array Question
Posted: Sun Oct 04, 2015 6:28 pm
by SparkOut
In the case above, sorting keys is irrelevant. However, if you step through the code and watch the variables in the debugger, when it comes to getting the keys of an array, you might see the values, for instance
1
4
2
3
with no indication of any reason why the lines of the keys are "out of order". The answer is, they are not out of order, since there is no order kept. The fact that you have numerical indexes for the keys is not related - the keys are just string representations of the numbers. The keys could be "alpha"," beta","gamma","delta" in text, so not even alphabetical order is relevant.
As long as you understand this, there is no problem at all. When you try and reconcile other expectations with the way LiveCode arrays work you may come unstuck, for instance in terms of a push/pop scenario. How would you define the "last" key?
Your idea of using a separate index variable to manage the key extents is fine and shows you have realised some of the concepts required. It is a little more to remember, but if you know you have to manage that, it is perfectly feasible.
Re: Array Question
Posted: Mon Oct 05, 2015 3:02 am
by dunbarx
Hi.
What everyone said.
It is common practice to extract array data into the clear with the "combine" command, and do all sorting and rearranging in that world, with whatever required patterns taken at that time. One might call that world "real time", as opposed to "array time".
The data can then immediately be split back into array form if desired for the compact data crunching that arrays do so well. This going back and forth between array time and real time may seem tedious, but it is the way arrays work in LC. You get used to it.
Craig Newman
Re: Array Question
Posted: Mon Oct 05, 2015 7:43 am
by dave.kilroy
As LiveCode is a typeless language it does conversions in the background and hides a log of complexity from us (which usually is a good thing) - but if you want to know what is really going on in your code it's best to have an understanding of what the LC engine is doing out-of-sight in exactly the way that CoreySchroeder is investigating.
I think of arrays as binary - falling on the binary side of the text/binary divide
Although actually there are three data types in LC: numbers, text and binary - actually I'm wrong and have just read there are four! I'll let Frazer explain
https://livecode.com/binary-vs-text/