Sort multidimensional array

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

Thierry
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 875
Joined: Wed Nov 22, 2006 3:42 pm

Re: Sort multidimensional array

Post by Thierry » Tue Mar 02, 2021 9:56 am

Simon Knight wrote:
Tue Mar 02, 2021 8:45 am
The main speed problem was caused by passing a copy
of the complete data variable to a function that was being called over a million times.
Hi Simon,

I'm on the same board as you, and I often use this little @ gremlin,
but not always as, like everything, it has its pros and cons.

However, in this thread context,
stam function() will not be called million of times
and
the passing array will not be copied
as it is not edited/updated inside the calling function.
- See bob's link to a more verbose explanation...

Hope that clarify a bit

Regards,
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!

Thierry
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 875
Joined: Wed Nov 22, 2006 3:42 pm

Re: Sort multidimensional array

Post by Thierry » Tue Mar 02, 2021 10:00 am

stam wrote:
Tue Mar 02, 2021 9:22 am
bobcole wrote:
Tue Mar 02, 2021 4:31 am
...there was an issue with using the "do" command....
...somehow related to Apple not liking programs that have potentially self-altering code in their App Store....
I must say, that seems unlikely.... I’d be surprised if Apple did a code-level review of apps (but really have no idea).
....
I do believe the same as Stam.

Regards,
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!

Simon Knight
Posts: 854
Joined: Wed Nov 04, 2009 11:41 am
Location: Gunthorpe, North Lincs, UK

Re: Sort multidimensional array

Post by Simon Knight » Tue Mar 02, 2021 10:01 am

@Thierry,

My fault as I raised the speed bumps as an aside.

Simon
best wishes
Skids

Thierry
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 875
Joined: Wed Nov 22, 2006 3:42 pm

Re: Sort multidimensional array

Post by Thierry » Tue Mar 02, 2021 10:54 am

Hi Stam,

Here is a variant which is slightly faster and using less memory,
but of course this has to be proved :)

Code: Select all

function sortArray @pArray, pDirection, pSortType, pKey
   local tNextIndex, tSortText, tSortedIndex 
   get the keys of pArray
   put "sort lines of IT [[pDirection]] [[pSortType]] by pArray[each]" into tSortText //1-dimensional array
   if pKey is not empty then put "[pKey]" after tSortText //multidimensional array
   do merge(tSortText)
   repeat for each line tKey in IT
      add 1 to tNextIndex
      -- put pArray[tKey] into tSortedArray[tNextIndex]
      put tKey into tSortedIndex[tNextIndex] -- !!!! NEW WAY !!!!!!
   end repeat
   return tSortedIndex
end sortArray


Code: Select all

on test_sorting_array
   local X = "ccc,eee,ddd,xxx,bbb,ppp,aaa"
   split X by comma
   put X[1] && X[2] &cr into fld 1 --> ccc eee
   
   put sortArray(  X, "ascending", "text") into I
   
   put X[ I[ 1]] && X[ I[ 2]] &cr after fld 1 --> aaa bbb

end test_sorting_array

Happy coding
Last edited by Thierry on Tue Mar 02, 2021 12:05 pm, edited 2 times in total.
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!

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

Re: Sort multidimensional array

Post by stam » Tue Mar 02, 2021 11:14 am

Thierry wrote:
Tue Mar 02, 2021 10:54 am
Here is a variant which I guess
is slightly faster and using less memory,
but of course this has to be proved :)
Thanks as always Thierry!
However that won't sort multidimensional arrays i don't think? you don't make use of [pKey] and the code looks fairly identical to the previous one you posted:)

With your help i had posted my 'final' code here, catering for both 1-dimensional and multidimensional arrays.

If i remove the error checking code for simplicity this was the final code based on your help:

Code: Select all

function sortArray @pArray, pDirection, pSortType, pKey
   local tNextIndex, tSortedArray, tSortText
   
   get the keys of pArray
   put "sort lines of IT [[pDirection]] [[pSortType]] by pArray[each]" into tSortText //1-dimensional array
   if pKey is not empty then put "[pKey]" after tSortText //multidimensional array
   do merge(tSortText)
   repeat for each line tKey in IT
      add 1 to tNextIndex
      put pArray[tKey] into tSortedArray[tNextIndex]
   end repeat
   return tSortedArray
end sortArray
I had included error-checking code to help with my debugging and in way of some documentation, but it isn't actually needed. I did check it with your testing example by setting pKey to empty to sort that 1-dimensional array; setting pDirection and pSortType empty will default to ascending & text respectively.

One handler to rule them all! I think that's better?

Thierry
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 875
Joined: Wed Nov 22, 2006 3:42 pm

Re: Sort multidimensional array

Post by Thierry » Tue Mar 02, 2021 11:19 am

stam wrote:
Tue Mar 02, 2021 11:14 am
Thierry wrote:
Tue Mar 02, 2021 10:54 am
Here is a variant which is slightly faster and using less memory,....
However that won't sort multidimensional arrays i don't think?
you don't make use of [pKey] and the code looks fairly identical to the previous one you posted:)
Ok, some misunderstanding.... :evil:

I've edited my previous post, using your latest nice handler with some little changes!

Hope seeing the difference is more obvious by now?

Thierry
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!

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

Re: Sort multidimensional array

Post by stam » Tue Mar 02, 2021 12:32 pm

Thanks Thierry - but that confuses me more :) (easily done mind you...)

Your handler returns a sorted index, not a sorted array, when i test this with a multidimensional array.
As an example, when running my handler to sort a multidimensional array by the key ["identifier"] in descending order, i get this:
my way.jpg
Running your new handler to sort my multidimensional array, i get this back:
new way.jpg
instead of a sorted multidimensional array.

I guess i could use this to build a new array or modify the existing one, but not sure how that's better?
Or maybe i'm doing something wrong?

Stam

Thierry
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 875
Joined: Wed Nov 22, 2006 3:42 pm

Re: Sort multidimensional array

Post by Thierry » Tue Mar 02, 2021 1:18 pm

stam wrote:
Tue Mar 02, 2021 12:32 pm
Thanks Thierry - but that confuses me more :)
(easily done mind you...)
Welcome to the club :)
Or maybe i'm doing something wrong?
Sure :)

From my previous post, how to use it:

Code: Select all

on test_sorting_array
   ...
   put sortArray(  X, "ascending", "text") into I
   
   put X[ I[ 1]] && X[ I[ 2]] &cr after fld 1 --> aaa bbb
   ...
I rewrite it again in a more verbose way:

Code: Select all

on test_sorting_array
   ...
   put sortArray(  X, "ascending", "text") into textAscendingIndex
   put sortArray(  X, "descending", "text") into textDescendingIndex
   
   put textAscendingIndex[ 1] into firstIndex
   put textAscendingIndex[ 2] into secondIndex
   
   put X[ firstIndex]  && X[ secondIndex]  --> aaa bbb
   ...
The idea is there is no copy of the original array, which can be hudge
and the data returned by the sortArray() function is smaller.
This will certainly optimize the speed and the footprint of the function,
and, as a bonus you can generate different index with the same data...

probably the name of the function should be changed then:

sortArray() --> buildSortedIndexFromArray()

So, better or worse :)

May be go for a lunch and a coffee before reading this :wink:

Kind regards,
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!

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

Re: Sort multidimensional array

Post by stam » Tue Mar 02, 2021 2:47 pm

Thanks Thierry - i think i get it now -- it's not so much a array.sort method but rather a way to refer to the elements of the array with a different index.
I get how it this will be more lightweight especially when dealing with large arrays shifting binaries about etc.

Using it is just slightly more complex and maybe less helpful for my specific use case (the example i showed was from data that will populate the dgData of a data grid - for that i'd need to pass an array so don't think i could use this, but happy to stand corrected ;)).

A complimentary approach and a useful tool rather than a replacement?
i'll do some speed tests on a large array when i'm back from my actual day job, curious to see what the performance difference will be...

Thanks for taking time to explain this!
Stam

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7233
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Sort multidimensional array

Post by jacque » Tue Mar 02, 2021 8:01 pm

bobcole wrote:
Tue Mar 02, 2021 4:31 am
Also, I seem to recall that there was an issue with using the "do" command.
If I remember correctly, it has somehow related to Apple not liking programs that have potentially self-altering code in their App Store.
Anyone familiar with that issue?
Sorry, it is only a vague recollection.
Apple forbids self-modifying code, but I don't think they review the app that deeply. But if you get caught you'll lose your developer account. On the other hand, "do" isn't self-modifying in this case.

The main objection to "do" (and "value") is that they need to load the compiler which introduces overhead. In the case of the merge command you should get the same result using "get" instead, which has no extra overhead.

Code: Select all

get merge(tSortText)
In this case "do" is only used once so the overhead will be minimal but I try to avoid it whenever possible anyway.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

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

Re: Sort multidimensional array

Post by stam » Wed Mar 03, 2021 12:03 am

jacque wrote:
Tue Mar 02, 2021 8:01 pm
The main objection to "do" (and "value") is that they need to load the compiler which introduces overhead. In the case of the merge command you should get the same result using "get" instead, which has no extra overhead.

Code: Select all

get merge(tSortText)
In this case "do" is only used once so the overhead will be minimal but I try to avoid it whenever possible anyway.
On testing get merge() fails; do merge() works.
i tried changing this to get merge(tSortText) and it failed: Instead of evaluating the statement, 'it' just contains the text that was in tSortText and the handler returns a single integer. Changing it back to do merge(tSortText) returned the sorted indices of the array and returns the sorted array (that was the only word changed in my handler sortArray above).

Is this expected behaviour?

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7233
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Sort multidimensional array

Post by jacque » Wed Mar 03, 2021 7:11 am

Sorry, was working from memory and goofed. Try

Code: Select all

put merge(tSortText) into it
And since I'm still working from memory, if that doesn't work use "do". :)

Edit: I think I see now why this won't work. Merge requires a string, and tSortText isn't one. Using "do" forces evaluation. You could use "get" by creating a quoted string that includes the bracketed variables instead.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

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

Re: Sort multidimensional array

Post by bogs » Wed Mar 03, 2021 11:25 am

jacque wrote:
Wed Mar 03, 2021 7:11 am
You could use "get" by creating a quoted string that includes the bracketed variables instead.
So, this sounds like another one of those selectedLine things, eh? Tell me, would 'the value of' or 'the text of' work in front of the merge for this, like it does with selectedLine?

I'm beginning to think that Craig is right, "DO" is the answer to everything ;)
Image

Thierry
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 875
Joined: Wed Nov 22, 2006 3:42 pm

Re: Sort multidimensional array

Post by Thierry » Wed Mar 03, 2021 11:31 am

Sorry, was working from memory and goofed...
I think I see now why this won't work. Merge requires a string, and tSortText isn't one.
Mmm, sorry but
- tSortText IS a string
- the result of merge() IS a string too.
- the sort command IS NOT expecting a string as a parameter

Checking sort in the dictionary we can see that direction and sortType are enum type,
which is why the merge() alone won't help.

The DO command will compile and execute the returned string of merge().

That said , the merge() isn't mandatory; you can use format() or
the classic: put x && y ... into tSortText

So either code a list of if .. else ...
OR use the do merge() trick for a one line coding,
and accept the pros and cons of each solution.

About the DO and its speed:
if you do this:

repeat with i=1 to 10000000
DO "...."
end repeat
put "Are you still there?"

not too good, but:

on mouseUp
DO "...."
end mouseUp

you''ll hardly notice a speed problem...

Have a nice day,

Thierry
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!

Thierry
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 875
Joined: Wed Nov 22, 2006 3:42 pm

Re: Sort multidimensional array

Post by Thierry » Wed Mar 03, 2021 11:43 am

bogs wrote:
Wed Mar 03, 2021 11:25 am
I'm beginning to think that Craig is right, "DO" is the answer to everything ;)
DO NOTHING is the answer to everything ;)
!
SUNNY-TDZ.COM doesn't belong to me since 2021.
To contact me, use the Private messages. Merci.
!

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”