Parsing arrays

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

WebiWan
Posts: 22
Joined: Fri Apr 20, 2018 2:21 am

Parsing arrays

Post by WebiWan » Tue Dec 31, 2019 12:51 am

Hi all...

As usual, I'm hoping this is some quirk of Livecode that has a simple fix. I'm writing a routine that updates our company database with data from the SQLite db file associated with our remote support software. The database calls are working fine and the result (using test parameters) is an array with 71 keys, each of which has 10 subkeys.

However, when I try to parse the array like this:

Code: Select all

repeat for each element x in myArray
         put myArray[x][1] into tvMake
         put myArray[x][2] into tvModel 
         put myArray[x][3] into tvCompName 
         put myArray[x][4] into tvProdNum
         put myArray[x][5] into tvSerial 
         put myArray[x][6] into tvOSName
         put myArray[x][7] into tvProcessor
         etc...
I get an error that says Array: bad index expression on the very first put statement.

If I do it this way:

Code: Select all

put the number of elements in myArray into tvLong
      repeat with x = 1 to tvLong
         put myArray[x][1] into tvMake
         put myArray[x][2] into tvModel 
         put myArray[x][3] into tvCompName 
         put myArray[x][4] into tvProdNum
         put myArray[x][5] into tvSerial 
         put myArray[x][6] into tvOSName
         put myArray[x][7] into tvProcessor
         etc...
It goes through each line as expected but puts none of the data into the variables. They're all blank.

I tried re-installing Livecode Community 9.5 and then I updated it to 9.5.1, because once a few years ago something got corrupted and it was causing strange errors. But that didn't do anything except keep me occupied for 15 minutes.

Dave

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9823
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Parsing arrays

Post by FourthWorld » Tue Dec 31, 2019 2:39 am

The symptoms described for both cases would be met if the variable myArray is not actually an array.

How is that variable populated?
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Parsing arrays

Post by dunbarx » Tue Dec 31, 2019 5:11 am

Dave.

Do you see what Richard means? Is myArray possibly an ordinary variable, as opposed to an array variable? That is why he asks how that variable is constructed.

Craig

bogs
Posts: 5435
Joined: Sat Feb 25, 2017 10:45 pm

Re: Parsing arrays

Post by bogs » Tue Dec 31, 2019 7:34 am

You can actually test whether or not your array is an array with either put or answer, like this -

put myArray is an array -- will either come back true or false
Apic_isAnArray.png
I was misled...
Image

mrcoollion
Posts: 720
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Parsing arrays

Post by mrcoollion » Tue Dec 31, 2019 3:36 pm

Would this work?

Code: Select all

repeat for each key tKey in myArray
   put myArray[tKey] into tLineData
   put tLineData[1] into tvMake
   put tLineData[2] into tvModel 
   put tLineData[3] into tvCompName 
   put tLineData[4] into tvProdNum
   put tLineData[5] into tvSerial 
   put tLineData[6] into tvOSName
   put tLineData[7] into tvProcessor  
end repeat
// Or
repeat for each key tKey in myArray
   put myArray[tKey][1] into tvMake
   put myArray[tKey][2] into tvModel 
   put myArray[tKey][3] into tvCompName 
   put myArray[tKey][4] into tvProdNum
   put myArray[tKey][5] into tvSerial 
   put myArray[tKey][6] into tvOSName
   put myArray[tKey][7] into tvProcessor  
end repeat
Regards,

Paul

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Parsing arrays

Post by dunbarx » Tue Dec 31, 2019 5:34 pm

Paul.

The issue is not that the "reading" of the array variable contained an error in syntax , but that the attempt may have been made on an ordinary variable. Each type is both read and built differently, and you cannot mix the two.

The only difference between your snippet and the original is one nest fewer. Each seems fine, for an array.

Craig

WebiWan
Posts: 22
Joined: Fri Apr 20, 2018 2:21 am

Re: Parsing arrays

Post by WebiWan » Tue Dec 31, 2019 8:57 pm

I agree, both seem fine for an array. And yet one will not run at all and the other assigns no data to the variables. Do you have any thoughts on that?

It seems Livecode is really buggy. I had a problem a while back that every "answer" statement would cause the stack and the IDE crash and no one had a clue what that was about. Are there less buggy versions available?

WebiWan
Posts: 22
Joined: Fri Apr 20, 2018 2:21 am

Re: Parsing arrays

Post by WebiWan » Tue Dec 31, 2019 9:04 pm

FourthWorld wrote:
Tue Dec 31, 2019 2:39 am
The symptoms described for both cases would be met if the variable myArray is not actually an array.

How is that variable populated?
It's populated through a query to the database. When I step through each line myArray shows up in the variables section as an array. In other words it has 71 numbered keys each having 10 subkeys. I just tried bogs' statement below and it returns "true."

WebiWan
Posts: 22
Joined: Fri Apr 20, 2018 2:21 am

Re: Parsing arrays

Post by WebiWan » Tue Dec 31, 2019 9:14 pm

mrcoollion wrote:
Tue Dec 31, 2019 3:36 pm
Would this work?

Code: Select all

repeat for each key tKey in myArray
   put myArray[tKey] into tLineData
   put tLineData[1] into tvMake
   put tLineData[2] into tvModel 
   put tLineData[3] into tvCompName 
   put tLineData[4] into tvProdNum
   put tLineData[5] into tvSerial 
   put tLineData[6] into tvOSName
   put tLineData[7] into tvProcessor  
end repeat
// Or
repeat for each key tKey in myArray
   put myArray[tKey][1] into tvMake
   put myArray[tKey][2] into tvModel 
   put myArray[tKey][3] into tvCompName 
   put myArray[tKey][4] into tvProdNum
   put myArray[tKey][5] into tvSerial 
   put myArray[tKey][6] into tvOSName
   put myArray[tKey][7] into tvProcessor  
end repeat
Regards,

Paul
Unfortunately no. I had tried the second example before and it assigns no values to the variables. Your first example I had not tried but it does the same thing.

I'm starting to think I should install the IDE on another computer and try it there. There really isn't anything else that can describe this behavior.

bogs
Posts: 5435
Joined: Sat Feb 25, 2017 10:45 pm

Re: Parsing arrays

Post by bogs » Tue Dec 31, 2019 9:22 pm

WebiWan wrote:
Tue Dec 31, 2019 9:04 pm
I just tried bogs' statement below and it returns "true."
Not to take undue credit, the statement actually was modified directly from the dictionary example :wink:

Fortunately, it appears you are at least starting with a real array. Did you also check it before you start running that loop? (Same code example will give you true/false before you start the operation).
Image

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9648
Joined: Wed May 06, 2009 2:28 pm
Location: New York, NY

Re: Parsing arrays

Post by dunbarx » Tue Dec 31, 2019 10:08 pm

When I step through each line myArray shows up in the variables section as an array. In other words it has 71 numbered keys each having 10 subkeys. I just tried bogs' statement below and it returns "true."
Well, we are at least getting somewhere. When you do step through, does the very first line:

Code: Select all

 put myArray[x][1] into tvMake
put anything into tvMake?

And if you run this:

Code: Select all

on mouseUp
   put "X" into myArray["1"]["2"]
end mouseUp
does the variable watcher show something like this:
Screen Shot 2019-12-31 at 4.05.57 PM.png
Screen Shot 2019-12-31 at 4.05.57 PM.png (6.02 KiB) Viewed 8385 times
Just to make sure you have the array set up properly.

Craig

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9823
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Parsing arrays

Post by FourthWorld » Tue Dec 31, 2019 10:26 pm

WebiWan wrote:
Tue Dec 31, 2019 9:14 pm
I'm starting to think I should install the IDE on another computer and try it there. There really isn't anything else that can describe this behavior.
Probably not worth the trouble. If there was something fundamentally broken with arrays it would likely have shown up in automated testing, and even if it somehow slipped through there we'd see the forums filled with confused comments from people affected by this very popular set of language features.

It really would be helpful to see the code for how the variable is populated.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

AxWald
Posts: 578
Joined: Thu Mar 06, 2014 2:57 pm

Re: Parsing arrays

Post by AxWald » Wed Jan 01, 2020 3:20 pm

Hi,
WebiWan wrote:
Tue Dec 31, 2019 8:57 pm
Are there less buggy versions available?
For such I'd recommend LC 6.7.10/11. It is, in my opinion, the last version actually deserving the attribute "Stable". For sure, it lacks a lot of the bells & whistles of the flashier new versions (7, 8, 9), and even a few useful new features. But it's sufficiently bug-free, and it's fast & reliable. Which is a chronic deficiency in the new versions, IMHO.

To your question:
I assume it's a misinterpretation of "elements" - elements are the values of the array, not the keys! So if you plan to use it in square brackets later, "elements" are a no-no! I wrote some code to clarify this. Guess I'll explain it at first.
  1. I populate the Array. It will result in this:
    array.png
    the Array
    array.png (7.37 KiB) Viewed 8296 times
  2. Then I have the previous attempts/ examples.
    1. WebiWan 1: Your X is the whole sub-array of A, not an (expected) key. Cannot work.
    2. WebiWan 2: Your X is the ordinal number of a first level key, not a key itself. Will not work, or give wrong results.
    3. mrcoollion 1: Correctly retrieves the first key (A), but then assumes the second level keys are numeric. They are here, but you cannot rely on it.
    4. mrcoollion 2: Basically the same.
  3. Last, a way to correctly loop through the values using the keys. I added a few lines to output a table-like representation of the data in the clipboard. It's always helpful for a quick reference ;-)
Make a new stack with 1 button, and put this into the btn script. "Apply", and hit the btn. Step through & watch the variables - you'll see why the work or not. Hit "Continue" (F5) to skip to the next example:

Code: Select all

on mouseUp
   repeat for each char C in "ABCDE"               --  1st level keys
      repeat for each char N in "12345"            --  2nd level keys
         put "Val_" & C & N into myArray[C][N]     --  values
      end repeat
   end repeat
   breakpoint
   
   --  WebiWan 1:
   repeat for each element X in myArray
      put myArray[X][1] into myVar            --  fails because X itself is an array
   end repeat
   breakpoint
   
   --  WebiWan 2:
   repeat with X = 1 to (the number of elements in myArray)
      put myArray[X][1] into myVar            --  fails because X is not a Key (ABC ... are!)
   end repeat
   breakpoint
   
   --  mrcoollion 1:
   repeat for each key T in myArray
      put myArray[T] into myLine
      put myLine[1] into myvar                --  this works here, because 1 is actually a 2nd Level key (123 ...)
   end repeat
   breakpoint
   
   --  mrcoollion 2:
   repeat for each key T in myArray
      put myArray[T][1] into myVar            --  this works here, because 1 is actually a 2nd Level key (123 ...)
   end repeat
   breakpoint
   
   --  Try this!
   repeat for each key k1 in myArray                  --  loop through all 1st level keys
      repeat for each key k2 in myArray[k1]           --  loop through all 2nd level keys
         put myArray[K1][k2] into myVar               --  and hit the values
         put k1 & tab & k2 & tab & myArray[K1][k2] & CR after myTable        --  make table :)
      end repeat
   end repeat
   delete char -1 of myTable
   set the clipboarddata["text"] to myTable
end mouseUp
Arrays in LC are basically simple key-value pairs (1-dimensional).
They are not table-like structures (2-dimensional) like in databases!
(LC still has no data type for handling database data, nor a good way to display it. There's the "Table field" that never got finished, and there's the "DataGrid" whose main virtue is repelling newbies by it's sheer weight & complexity.)

To work with database data in arrays, you need to blow 'em up to the second dimension - means, each key in the first dimension (the record designator: ID, for instance), has as value a sub-array (the record data).
And each value in this record data sub-array has its own key again - the 2nd level key, or the field name.

You got the basic array right, as it seems, but got messed up addressing it. It takes some time to get used to it ;-)

Meanwhile you may use a function I wrote to make my days more enjoyable - it allows you to create arrays where the keys have meaningful names.
Assume you have a table with fields of "PersonID", PersonName", PersonHeight". You got the data via revdb_something in tab-return format and want it in a nice array. (I added code to provide some sample data)

Code: Select all

on mouseUp
   --  load some data:
   put "100" & tab & "Joe" & tab & "80" & CR & \
         "101" & tab & "Jane" & tab & "60" & CR & \
         "102" & tab & "Jimmy" & tab & "30" into myData
   --  load the field names
   put "PersonID" & tab & "PersonName" & tab & "PersonWeight" into myKeys
   --  make the array:
   put Data2Array(myData, myKeys, 1) into myArray   --  full version
   --  put Data2Array(myData) into myArray          --  all autonumbered keys
   --  put Data2Array(myData, myKeys) into myArray  --  records autonumbered, but field names
   breakpoint
end mouseUp

function Data2Array theData, theKeys, theKeyCol
   /*
   Use this to translate tabular data to an 2D array - myArr[x][y]
   The keys of the array can be just numbered (autoinc), or can be named according
   the contents of one of the columns (for 1st level) resp. according a list of field names (2nd level)
   
   "theData" (tab-del TEXT, ex. data from a db): the data to translate into a 2D array.
   
   "theKeys" (optional, tab-del TEXT): the names of the 2nd level keys. Else autoInc INT.
   
   "theKeyCol" (optional, INT): designates the  # of the column that will become the 1st level key. Else autoInc INT.
   (Hint: this column MUST NOT contain dupes, so best only use for an autoinc unique id!)
   
   Returns the desired array. Has no errors :)
   
   © axwald 2019, GPL V3
   */
   set itemdel to tab
   put 0 into MyLCnt
   repeat for each line L in theData
      add 1 to myLCnt
      put 0 into myICnt
      repeat for each item I in L
         add 1 to myICnt
         switch
            case (theKeys is empty) and (theKeyCol is empty)               --  myArr[1][1]
               put I into myArr[myLCnt][myICnt]
               break
            case (theKeys is not empty) and (theKeyCol is empty)           --  myArr[1][aColName]
               put I into myArr[myLCnt][(item myICnt of theKeys)]
               break
            case (theKeys is empty) and (theKeyCol is not empty)           --  myArr[anID][1]
               put I into myArr[(item theKeyCol of L)][myICnt]
               break
            case (theKeys is not empty) and (theKeyCol is not empty)       --  myArr[anID][aColName]
               put I into myArr[(item theKeyCol of L)][(item myICnt of theKeys)]
               break
         end switch
      end repeat
   end repeat
   return myArr
end Data2Array
Have fun, hope I could help! And a happy new year to all!
All code published by me here was created with Community Editions of LC (thus is GPLv3).
If you use it in closed source projects, or for the Apple AppStore, or with XCode
you'll violate some license terms - read your relevant EULAs & Licenses!

mrcoollion
Posts: 720
Joined: Thu Sep 11, 2014 1:49 pm
Location: The Netherlands

Re: Parsing arrays

Post by mrcoollion » Wed Jan 01, 2020 5:24 pm

To see how your array actually looks (after confirming that it actually is an array ) you could add a treeview widget on a card and put the array in the Treeview with the following code.

Code: Select all

set the arraydata of widget ArrayView to myArray
Maybe then you can see if there is anything different to the array then you expected that could explain the outcome of your script? This has helped me working with array's.
Regards,

Paul

WebiWan
Posts: 22
Joined: Fri Apr 20, 2018 2:21 am

Re: Parsing arrays

Post by WebiWan » Wed Jan 01, 2020 7:19 pm

bogs wrote:
Tue Dec 31, 2019 9:22 pm
WebiWan wrote:
Tue Dec 31, 2019 9:04 pm
I just tried bogs' statement below and it returns "true."
Not to take undue credit, the statement actually was modified directly from the dictionary example :wink:

Fortunately, it appears you are at least starting with a real array. Did you also check it before you start running that loop? (Same code example will give you true/false before you start the operation).
Yes, I actually ran that immediately before the loop.

Post Reply

Return to “Getting Started with LiveCode - Experienced Developers”