Why Array over list

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: Why Array over list

Post by dunbarx » Thu Oct 27, 2016 4:25 am

Right.

Early on, I wanted to "extract" what I called intermediate values in a multi-dimensional array, to pull out, for example, the value of "" in myArray{"A"]["B"]["C"].

As Mark shows us, you cannot, you must:

Code: Select all

on mouseUp
   put "4" into myArray{"A"]["B"]
   put "42" into myArray{"A"]["B"]["C"]
   put myArray["A"]{"B"] into xx
end mouseUp
This gives "42" (the value of the element "C").

Craig

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10043
Joined: Sat Apr 08, 2006 7:05 am
Contact:

Re: Why Array over list

Post by FourthWorld » Thu Oct 27, 2016 2:46 pm

dunbarx wrote:Early on, I wanted to "extract" what I called intermediate values in a multi-dimensional array, to pull out, for example, the value of "" in myArray{"A"]["B"]["C"].

As Mark shows us, you cannot, you must:

Code: Select all

on mouseUp
   put "4" into myArray{"A"]["B"]
   put "42" into myArray{"A"]["B"]["C"]
   put myArray["A"]{"B"] into xx
end mouseUp
This gives "42" (the value of the element "C").
It should give an array rather than a single string value like the numerals "42", since it's returning the array that replaced "4" at myArray["A"]["B"].

The example above is equivalent to:

Code: Select all

put "42" into tSomeOtherArray["C"]
put "4" into myArray["A"]["B"]
put tSomeOtherArray into myArray["A"]["B"]
By adding the creation of the array tSomeOtherArray as an extra step it becomes clearer that we're overwriting the "4" that had been the value of myArray["A"]["B"].

Remember Rule 3 of the three rules that define associative arrays:
An array element's value can be a string, or binary data, or another array.
It can be any one of those, but only one.
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: Why Array over list

Post by AxWald » Sat Oct 29, 2016 3:00 pm

Hi, thank you a lot, all of you!

I actually had a heavy misconception about arrays. Since I'm coming from database work, all "data" translates into something table-like for me ...
So I guess I learned something now:
  1. Arrays are not tables. Arrays are just key/value pairs, where value can be another array.
  2. If you throw data into an array, when it comes out again, the previous order may be gone.
  3. If you split data by row only you'll get nice integer auto-increment keys :)
  4. Arrays can be used very well for loops with table data! (See example below)
The further benefits of Key/Value pairs are still beyond my horizon. XML or JSON is, for me, work of the "The Evil One™", maliciously crafted to drown us poor mortals in ASCII garbage & redundancies. Maybe it's even made too hide from those young coders the ultimate enlightenment - the insight into the clear, logical, efficient world of relational databases ... Well. You never know. Anyways.

But I found a great use for arrays: As mentioned, splitting a big bunch of delimited data by row gives me a numerical indexed array of lines. And this now is the good stuff for looping:
  • It is as flexible as looping through delimited data using "repeat with i = 1 to the number of lines of ", where you can change the real data during the loop & have a counter, but which is rather slow when you have a lot of data.
  • And it's even faster than looping using "repeat for each line MyLine in ", where you cannot change the data during loop (w/o builing a second variable) and don't have a counter (and thus no access to items in other lines).
  • And, most important, you can not only change items over all your data, you can even add & delete whole lines, during the loop, without loosing orientation!
It happened that, in my work, I just broke my head over such a problem.
What follows may not be too interesting, but can be seen as an example of what can be done with LC besides "apps", and shows my first real use of arrays. You may skip it, your choice :)
Example from real life:

In the automated processing of jobs from a web shop (the jobs come via LC socket server running unattended, as a headless service ...), after the approval of a job, my code must take care that the articles are available. This is made separate for each supplier, because all of them work in a different manner. One main supplier receives 1 order per job; his venerable dbase system monitors a FTP server where I deposit single CSV files in a very crude format.
(The actual work of collecting, distributing and sending the orders is done by another headless LC standalone running as cmd line tool started by "schtasks"/ "cron"; this module here only massages & stores the data in an approbate form ...)

This alone wouldn't be much hassle; but the suppliers dbase does a strange handling of "pieces & packages" - means, if a Wine comes in packages of 6 bottles, and the customer wants 7 bottles, I must order 2 articles: one order for 1 package, and a separate one for 1 bottle. Crazy, right?
This means, I must be able to add lines to the order during the loop. And to save even more work (and to keep the loop fast & slender), it would be fine if I could add items to the line on the fly, and to change data outside of the looped line ...

That's the working code (might still have quirks, not yet fully tested & optimized):

Code: Select all

   repeat for each key i in MyJobArr                                   -- array of the whole job
      if item 18 of MyJobArr[i] = 2 then                                -- this is our supplier

         if item 3 of myJobArr[i] < item 9 of myJobArr[i] and \     -- pieces < package size
           (item 23 of myJobArr[i] is empty) and (item 22 of myJobArr[i] is empty) then
            put item 3 of myJobArr[i] into item 23 of myJobArr[i]
         else if item 3 of myJobArr[i] mod item 9 of myJobArr[i] <> 0 and \ -- piece & packg
           (item 23 of myJobArr[i] is empty) and (item 22 of myJobArr[i] is empty) then
            put the number of lines of the keys of myJobArr +1 into NewKey
            put myJobArr[i] into myJobArr[NewKey]                      -- duplicate line
            put item 3 of myJobArr[i] mod item 9 of myJobArr[i] \    -- fill in pieces
              into item 23 of myJobArr[NewKey]
            put item 3 of myJobArr[i] div item 9 of myJobArr[i] \     -- fill in packages
              into item 22 of myJobArr[i]
         else                                                      -- only packages
            if (item 23 of myJobArr[i] is empty) and (item 22 of myJobArr[i] is empty) then
               put item 3 of myJobArr[i] / item 9 of myJobArr[i] \
               into item 22 of myJobArr[i]
         end if

         put Kwote("13363") & ";" & \                            -- compose the nasty order
         kwote(MyOrderNr) & ";" & \
         kwote(format("%10s",item 16 of myJobArr[i])) & ";" & \
         kwote(combName(item 17 of myJobArr[i],item 20 of myJobArr[i])) & ";" & \
         kwote(format("%10s",item 22 of myJobArr[i])) & ";" & \
         kwote(format("%10s",item 23 of myJobArr[i])) & ";" & \
         kwote(format("%10s",format("%.2f",item 13 of myJobArr[i]))) & ";" & \
         kwote(format("%20s",item 21 of myJobArr[i])) & return after MyVar
      end if
   end repeat
   delete last char of MyVar
   put MyVar  -- ... doing whatever with this order
• "(item 23 of myJobArr is empty) and (item 22 of myJobArr is empty)" is a test if it's "fresh" data, or a already processed line: in items 22 & 23 I temp store the calculated package & piece values.
• Item 3 is the amount of pieces ordered by the customer, item 9 is the package size.
• The building of MyVar (= the resulting CSV) is left as a source of amusement ;-)

Have fun!
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!

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Contact:

Re: Why Array over list

Post by mwieder » Sat Oct 29, 2016 5:40 pm

Congratulations :!: Yes, those four points are indeed key to unlocking the mysteries and wonders of arrays.
The further benefits of Key/Value pairs are still beyond my horizon. XML or JSON is, for me, work of the "The Evil One™", maliciously crafted to drown us poor mortals in ASCII garbage & redundancies. Maybe it's even made too hide from those young coders the ultimate enlightenment - the insight into the clear, logical, efficient world of relational databases ... Well. You never know. Anyways.
Heh.
The advantage of arrays (hashes, JSON, xml, anything that deals with key-value pairs) is a flexible hierarchical data structure.
If you're using a relational database and somewhere along the way you realize that you need to rearrange the data: add new fields to accomodate an order of 7 bottles, etc) or worse, move fields from one table to another; you're in for a lot of maintenance work.

With key-value pairs you just add another item to a data structure and you're done. No need (famous last words) to mess with anything existing in the data.

And xml and JSON weren't necessarily meant to be human-readable, which is why all the extra and redundant text, they're designed to allow for easy processing of complicated data hierarchies. Trying to read your way through xml data and make sense of it isn't something I would recommend.

Code: Select all

 if item 3 of myJobArr[i] < item 9 of myJobArr[i] and \     -- pieces < package size
When I'm faced with something like this I like to create a set of constants:

Code: Select all

constant kPieces = 3
constant kPackageSize = 9
...
 if item kPieces of myJobArr[i] < item kPackageSize of myJobArr[i] and \     -- pieces < package size
as it makes my code easier to read later on, and if I have to rearrange items somewhere down the road I only have to change the constants in one place.

Post Reply