iOS Question Sorting Map

aaronk

Well-Known Member
Licensed User
Longtime User
Hi,

I am trying to work out how to sort a map.

I have it working fine with B4A but now using the same code on B4i and it's not working.

It seems to not sort it correctly on B4i. On B4A it sorts it fine. (using the same data)

The code I have used is:

B4X:
   Dim EventList as Map
   EventList.Initialize
    EventList.Put("1545915780827","ABC1")
    EventList.Put("1544739267005","ABC2")
    EventList.Put("1545869166546","ABC3")
    EventList.Put("1545869223365","ABC4")
    EventList.Put("1545869166766","ABC5")
    EventList.Put("1545869166582","ABC6")
    EventList.Put("1545870879803","ABC7")
    EventList.Put("1544739267025","ABC8")
    EventList.Put("1545870884867","ABC9")

   ' this will sort the map
    SortMapKeys(EventList,False)

I am sorting the Map with the following code (which works fine in B4A)
B4X:
Sub SortMapKeys (m As Map, SortAsc As Boolean)
    Private KeysList As List:KeysList.Initialize
    Private m2 As Map:m2.Initialize
   
    For Each item As String In m.keys
        KeysList.Add(item)
    Next
   
    KeysList.Sort(SortAsc)
 
    For x=0 To KeysList.Size - 1
        Private key As String = KeysList.Get(x)
        Private val As String = m.Get(key)
        m2.Put(key, val)
    Next
    m.Clear
    For Each m2Key As String In m2.Keys
        m.Put(m2Key, m2.Get(m2Key))
    Next
End Sub

I am then viewing the results:
B4X:
   DateTime.DateFormat = "EEEE d MMMM yyyy h:mma"
    For Each key As String In EventList.Keys  
        Log(key & "  " & DateTime.Date(key))
    Next

When I view the B4i log it shows:
B4X:
1545869223365  Thursday 27 December 2018  11:07am
1545870884867  Thursday 27 December 2018  11:34am
1544739267025  Friday 14 December 2018  9:14am
1545870879803  Thursday 27 December 2018  11:34am
1545869166546  Thursday 27 December 2018  11:06am
1545869166582  Thursday 27 December 2018  11:06am
1545869166766  Thursday 27 December 2018  11:06am
1545915780827  Friday 28 December 2018  12:03am
1544739267005  Friday 14 December 2018  9:14am

In B4A it shows (which is correct, so I guess my code should of worked):
B4X:
1545915780827  Friday 28 December 2018  12:03am
1545870884867  Thursday 27 December 2018  11:34am
1545870879803  Thursday 27 December 2018  11:34am
1545869223365  Thursday 27 December 2018  11:07am
1545869166766  Thursday 27 December 2018  11:06am
1545869166582  Thursday 27 December 2018  11:06am
1545869166546  Thursday 27 December 2018  11:06am
1544739267025  Friday 14 December 2018  9:14am
1544739267005  Friday 14 December 2018  9:14am

Any ideas on what I have done wrong?

I am wanting to sort the Ticks (time and date) which is stored in the Map as the Key, and then going to display the value based on the order the Ticks (time and date) is in.

If there is a better way, then can you provide an example as I have working on this for many days, and can't work out a better way in doing this.
 

William Lancee

Well-Known Member
Licensed User
Longtime User
Hi

You don't sort a map.

Just sort the key list and use it to reference the map.

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
    MainForm.Show
    Dim EventList As Map
    EventList.Initialize
    EventList.Put("1545915780827","ABC1")
    EventList.Put("1544739267005","ABC2")
    EventList.Put("1545869166546","ABC3")
    EventList.Put("1545869223365","ABC4")
    EventList.Put("1545869166766","ABC5")
    EventList.Put("1545869166582","ABC6")
    EventList.Put("1545870879803","ABC7")
    EventList.Put("1544739267025","ABC8")
    EventList.Put("1545870884867","ABC9")
    
    displaySortedMap(EventList, True)
End Sub

Sub displaySortedMap(m As Map, SortAsc As Boolean)
    Private KeysList As List:KeysList.Initialize
    Private m2 As Map:m2.Initialize
    For Each item As String In m.keys
        KeysList.Add(item)
    Next
    Log(KeysList)
    
    KeysList.Sort(SortAsc)

    DateTime.DateFormat = "EEEE d MMMM yyyy h:mma"
    For Each aKey In KeysList
        Log(m.Get(aKey) & "  " & DateTime.Date(aKey))
    Next
End Sub
 
Upvote 0

aaronk

Well-Known Member
Licensed User
Longtime User
Oh, I see now.

I have been trying to sort it and then load it back in again.

I go it working now. Thanks heaps!
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Good.

A caution though. The datetime variable is a Long Integer. The sort order of numbers is different than the sort order of equivalent strings.

In your case this won't matter, since time only increases and short strings precede long strings.

In any case, if you remove the quotes for the long integer keys, it will still work.

B4X:
 EventList.Put(1545870884867,"ABC9")

 For Each item As Long In m.keys
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
One final point. This is not the best use of maps, a more efficient approach would be to use the 'Type' and 'SortType' feature of B4X.

B4X:
Sub Process_Globals
    Type sortPair(theDate As Long, theValue As String)
End Sub

Dim EventList As List: EventList.Initialize
EventList.add(setPair(1545915780827, "ABC1"))
EventList.add(setPair(1544739267005, "ABC2"))
EventList.add(setPair(1545869166546, "ABC3"))
EventList.add(setPair(1545869223365, "ABC4"))
EventList.add(setPair(1545869166766, "ABC5"))
EventList.add(setPair(1545869166582, "ABC6"))
EventList.add(setPair(1545870879803, "ABC7"))
EventList.add(setPair(1544739267025, "ABC8"))
EventList.add(setPair(1545870884867, "ABC9"))
EventList.SortType("theDate", True)
Log(EventList)

Sub setPair(d As Long, s As String) As sortPair
    Dim sp As sortPair: sp.initialize
    sp.theDate = d
    sp.theValue = s
    Return sp   
End Sub
 
Upvote 0
Top