Array referencing

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

trevix
Posts: 962
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Array referencing

Post by trevix » Thu Oct 26, 2023 5:11 pm

Hello.
Small problem that gives me a headache:
I save values in array like

Code: Select all

put "Regular" into gPrefTF[gSport]["setting"]["DEFAdvantage"]
Now, the script in some cases needs to change the array path of "DEFAdvantage" to something like this:

Code: Select all

put "Regular" into gPrefTF["gPrefTvBox"]["gPrefTF"][gSport]["setting"]["DEFAdvantage"]
Since there are tens of array references in the same script, instead of having tens of "if then else", I tough of having a function in the stack that changes the reference like this:

Code: Select all

function PathToPref pValue
     if 1 = 1 then --this is where the choice is made
          put "gPrefTF[" & quote & "gPrefTvBox" & quote & "][" & gSport & "][" & quote & "setting" & quote & "][" & quote & pValue & quote & "]" into tPathToPref
     else
          put "gPrefTF[" & gSport & "][" & quote & "setting" & quote & "][" & quote & pValue & quote & "]" into tPathToPref
     end if
     return tPathToPref
end PathToPref
The idea was to call the function to replace the array path, like this.

Code: Select all

put "Regular" into value(PathToPref("DEFAdvantage"))
--OR
put value(PathToPref("DEFAdvantage")) into tSOmething
But, as usual, it doesn't work. Any idea?
Thanks
Trevix
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Array referencing

Post by stam » Thu Oct 26, 2023 9:02 pm

Does your if statement say

Code: Select all

If 1=1 then… 
or is that a typo?

If not a typo, how will that branch if the first statement always returns true?

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

Re: Array referencing

Post by dunbarx » Thu Oct 26, 2023 9:36 pm

Stam.

I use something like that as a "catchAll" in switch constructions, though these are invariably at the LAST case statement exclusively. In that sense, it will be interesting to see what the OP comes back with.

Craig

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

Re: Array referencing

Post by dunbarx » Thu Oct 26, 2023 9:48 pm

And this brings up an old suggestion of mine, dear to my heart, discussed in this forum, but that never much interested Scotland. I will say it again...

To add another control structure to "switch" (not forced to use either "break" of nothing at all) at the end of each case statement, to allow more than one case to fire if that case is valid. Currently, "break" exits the entire construct, leaving possible valid cases below unexamined. And having nothing at all executes every case regardless of validity.

If even one person asks me anything at all, I will dig up the early discussions and post the reference. Serious LC'ers only please. :wink:

Craig

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Array referencing

Post by stam » Thu Oct 26, 2023 10:12 pm

dunbarx wrote:
Thu Oct 26, 2023 9:48 pm
And this brings up an old suggestion of mine, dear to my heart, discussed in this forum, but that never much interested Scotland. I will say it again...

To add another control structure to "switch" (not forced to use either "break" of nothing at all) at the end of each case statement, to allow more than one case to fire if that case is valid. Currently, "break" exits the entire construct, leaving possible valid cases below unexamined. And having nothing at all executes every case regardless of validity.

If even one person asks me anything at all, I will dig up the early discussions and post the reference. Serious LC'ers only please. :wink:

Craig
Dear to your heart it may be… but relevant here it is not, as there are only two choices in the if block ;)

To digress from the OPs question:
What you’re suggesting goes against all paradigms of “switch” in every other language, and doesn’t offer anything you can’t do with a series of if statements one after the other (which I would argue would be less confusing), so not surprising your request has had no traction… Or at least that’s how I see it…

Roundtripping back to Trevix’s issue - we can only answer if the given code is a typo, as it stands it will never work…

trevix
Posts: 962
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Array referencing

Post by trevix » Fri Oct 27, 2023 8:43 am

stam wrote:
Thu Oct 26, 2023 9:02 pm
Does your if statement say

Code: Select all

If 1=1 then… 
or is that a typo?

If not a typo, how will that branch if the first statement always returns true?
Sorry for the misunderstanding: mine was only an example. I should have written "if tThis = tThat then"
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

trevix
Posts: 962
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Array referencing

Post by trevix » Fri Oct 27, 2023 9:54 am

Let me repost my problem with another example.
This code won't work but maybe it clarifies what I want to achieve:

Code: Select all

if tThis = tThat then
   put "gPrefTF[" & quote & "gPrefTvBox" & quote & "][" & gSport & "][" & quote & "setting" & quote & "]"  into tPathToPref
else
   put "gPrefTF[" & gSport & "][" & quote & "setting" & quote & "]" into tPathToPref
end if
--I am aware that the following line is not correct...
put "regular" into  tPathToPref & ["DEFAdvantage"]
So, the last line is not correct but how can I write it so that the value "regular" goes into the correct array key???
I would like to avoid using a "do" command, which, having a very long script, would multiply the lines of code.
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

stam
Posts: 2686
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Array referencing

Post by stam » Fri Oct 27, 2023 10:25 am

trevix wrote:
Fri Oct 27, 2023 9:54 am
--I am aware that the following line is not correct...
put "regular" into tPathToPref & ["DEFAdvantage"][/code]

So, the last line is not correct but how can I write it so that the value "regular" goes into the correct array key???
I would like to avoid using a "do" command, which, having a very long script, would multiply the lines of code.
OK, that makes more sense… but not sure you can do this without a do merge() statement, such as:

Code: Select all

Do merge(“put” && quote & "regular" & quote && “into  tPathToPref & [“ & quote &"DEFAdvantage" & quote &”]”
Possibly you could use value(tPathToPref), but that’s never worked for me when I’ve tried something like this previously

trevix
Posts: 962
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Array referencing

Post by trevix » Fri Oct 27, 2023 10:32 am

Possibly you could use value(tPathToPref), but that’s never worked for me when I’ve tried something like this previously
Yes, it doesn't work.
I wonder if using a function with the "@" before the parameter (pass reference) would work.
I did some experiment but to no avail.
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

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

Re: Array referencing

Post by mrcoollion » Fri Oct 27, 2023 11:19 am

Maybe this code helps somewhat.
For me it is not exactly clear what you want but this makes it possible to switch paths based upon your example.

Code: Select all

on mouseUp pMouseButton
   
   put PathToPref(1) into tPathNeeded
   breakpoint
end mouseUp

function PathToPref pValue
   // Some data in vars to test the procedure
   put "Sport" into gSport
   put "PrefTvBox" into gPrefTvBox
   put "PrefTF" into gPrefTF
   -----------------------------
   switch pValue
      case 1
         put "[gSport]" into tPath
         break
      case 2
         put "[gPrefTvBox][gPrefTF][gSport]" into tPath
         break
         
      default
         // if value is not1 or 2 do code at this place (no code yet)
   end switch
   put "gPrefTF"&tPath&"["&quote&"setting"&quote&"]["&quote&"DEFAdvantage"&quote&"]"into tPathToPref
   return tPathToPref
end PathToPref
Regards,

Paul

trevix
Posts: 962
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Array referencing

Post by trevix » Fri Oct 27, 2023 11:24 am

I don't understand how you plan to put a value in tPathNeeded (that is my point)
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1209
Joined: Thu Apr 11, 2013 11:27 am

Re: Array referencing

Post by LCMark » Fri Oct 27, 2023 12:03 pm

@trevix: If I understand what you want to do correctly, then you want to be able to access a deeply nested array element differently, based on some condition. To handle such cases, you can pass a 'sequence' as the key of an array which the engine will then use to dynamically descend into the array.

So, let's say you have an array (using LC10, array literal notation):

Code: Select all

put { "a": { "b": [10, 20, 30] }, \
        "b": { "a": [10, 20, 30] } } into tArray
Here there are two top-level keys, with slightly different structure underneath.

Let's say you want to access the second element of the nested sequence (i.e. value '20'). With normal array access you'd do:

Code: Select all

   put tArray["a"]["b"][2] into tAValue
   put tArray["b"]["a"][2] into tBValue
However, using the 'dynamic' feature you can also do it like this:

Code: Select all

   put [ "a", "b", 2 ] into tAPath
   put tArray[tAPath] into tAValue
   put [ "b", "a", 2 ] into tBPath
   put tArray[tBPath] into tBValue
So what you are trying to do in your (latest) code snippet is 'close' to what you can do, but the real version would be something more like:

Code: Select all

function PathToPref pValue
     if 1 = 1 then --this is where the choice is made
          put [ "gfPrefTvBox", gSport, "setting", pValue ] into tPathToPref
     else
          put [ gSport, "setting", pValue ] into tPathToPref
     end if
     return tPathToPref
end PathToPref
This function returns the 'path' to the key you want to manipulate. Then to set the 'DEFAdvantage' sub-key you'd do:

Code: Select all

put "regular" into gPrefTF[PathToPref("DEFAdvantage")]
The 'dynamic' path stuff is pretty flexible as any subscript expression *can* be an array, in which case the engine concatenates the resulting sequences before evaluating the element (or setting it). An alternative to the above would be (cut down version):

Code: Select all

   put [ gSport, "setting" ] into tPathToPref
   put "regular" into gPrefTF[tPathToPref]["DEFAdvantage"]
One thing you can't do (which you tried to do in your original code) was to select a different (root) variable dynamically - that's only possible by using do - but if you have a single root variable, with the first key selecting which 'root path' you want to take (like you have done) - then you should be good with the dynamic path stuff outlined above.

trevix
Posts: 962
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Array referencing

Post by trevix » Fri Oct 27, 2023 1:09 pm

Amazing! (and rather complex to grasp)
This is exactly what I need it,
THANKS!
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

LCMark
Livecode Staff Member
Livecode Staff Member
Posts: 1209
Joined: Thu Apr 11, 2013 11:27 am

Re: Array referencing

Post by LCMark » Fri Oct 27, 2023 1:43 pm

@trevix: Heh - my post was a little dense!

Perhaps a much shorter way to explain the 'dynamic path' feature is this:

Code: Select all

get tArray[A][B][C][D][E]
put tValue into tArray[A][B][C][D][E]
Is equivalent to:

Code: Select all

put [ A, B, C, D, E ] into tPath
get tArray[tPath]
put tValue into tArray[tPath]
Here you can have as many elements in tPath as you like, and can construct it however you like (it just needs to be an array which has keys 1..N).

Specifically, the new 'sequence literal' syntax in LC 10 which is used to populate tPath is just much more compact short-hand for:

Code: Select all

put empty into tPath
put A into tPath[1]
put B into tPath[2]
put C into tPath[3]
put D into tPath[4]
put E into tPath[5]
Hope that helps things a little clearer :)

trevix
Posts: 962
Joined: Sat Feb 24, 2007 11:25 pm
Location: Italy
Contact:

Re: Array referencing

Post by trevix » Fri Oct 27, 2023 1:52 pm

I think i can use it also like this:

Code: Select all

function PathToPref --on the stack
     if tThis = tThat then --choice
          put [ "gPrefTvBox", "gPrefTF", gSport ] into tPathToPref
     else
          put [ gSport ] into tPathToPref
     end if
     return tPathToPref
end PathToPref
and

Code: Select all

on Mouseup
put pChosenItem into gPrefTF[PathToPref()]["setting"]["DEFAdvantage"] --return the correct array path 
end Mouseup
Trevix
OSX 14.3.1 xCode 15 LC 10 DP7 iOS 15> Android 7>

Post Reply

Return to “Getting Started with LiveCode - Experienced Developers”