Android Question Accessing items of B4XOrderedMap by index?

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Experimenting with various sort algorithms.
It looks it is not possible to access items of a B4XOrderedMap by index, as there is no GetValueAt method as in the regular map.
There is a way round that but it seems a bit convoluted and inefficient:

B4X:
Sub SortOMStringIDX(arrString() As String, bCaseInsensitive As Boolean) As Int()
 Dim i As Long
Dim c As Long
Dim n As Long
Dim B4XOM As B4XOrderedMap
Dim lstKeys As List

If Check1DStringAllSame(arrString, bCaseInsensitive) Then
Dim arrIndex(1) As Int
arrIndex(0) = -1
Return arrIndex
End If

B4XOM.Initialize

For i = 0 To arrString.Length - 1
Dim lstIndexes As List
If B4XOM.ContainsKey(arrString(i)) Then
lstIndexes = B4XOM.Get(arrString(i))
Else
lstIndexes.Initialize
End If
lstIndexes.Add(i)
B4XOM.Put(arrString(i), lstIndexes)
Next

If bCaseInsensitive Then
B4XOM.Keys.SortCaseInsensitive(True)
Else
B4XOM.Keys.Sort(True)
End If

Dim arrIndex(arrString.Length) As Int

'we need this as it looks we can't access the items by index
lstKeys = B4XOM.Keys

For i = 0 To B4XOM.Size - 1
lstIndexes = B4XOM.Get(lstKeys.Get(i))
For c = 0 To lstIndexes.Size - 1
arrIndex(n) = lstIndexes.Get(c)
n = n + 1
Next
Next

Return arrIndex

End Sub

Sub Check1DStringAllSame(arrstring() As String, bCaseInsensitive As Boolean) As Boolean
 
 Dim i As Int
 Dim str As String
 
 If arrstring.Length = 1 Then
  Return True
 End If
 
 If bCaseInsensitive Then
  str = arrstring(0).ToLowerCase
  For i = 1 To arrstring.Length - 1
   If arrstring(i).ToLowerCase.CompareTo(str) <> 0 Then
    Return False
   End If
  Next
 Else
  str = arrstring(0)
  For i = 1 To arrstring.Length - 1
   If arrstring(i).CompareTo(str) <> 0 Then
    Return False
   End If
  Next
 End If
 
 Return True
 
End Sub

Would it be possible to add this method to the B4XOrderedMap?

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This is the correct way however I don't see why you need it here.

B4X:
For Each Key As Object In lstIndexes.Keys
Dim value As Object = lstIndexes.Get(Key)
Next
'or with latest version:
For Each Value As Object in lstIndexes.Values
..
Next

Note that it is more efficient than Map.GetKeyAt / GetValueAt.

Don't understand this. Do I not need the B4XOrderedMap?
I have version 9.80, but Values is not a method of the regular list.
The best I can do is:

B4X:
 For Each oKey As Object In B4XOM.Keys
  lstIndexes = B4XOM.Get(oKey)
  For c = 0 To lstIndexes.Size - 1
   arrIndex(n) = lstIndexes.Get(c)
   n = n + 1
  Next
 Next

How instead would you do the above nested loop?

RBS
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
How instead would you do the above nested loop?
This is how I get the keys and values of an orderedmap using the index:
B4X:
Private B4XOM As B4XOrderedMap
B4XOM.Initialize
    B4XOM.Put("1","test1")
    B4XOM.Put("5","test")
    B4XOM.Put("2","test2")
    B4XOM.Keys.Sort(True)
For i= 0 To B4XOM.Keys.Size-1
        Log(B4XOM.Keys.Get(i))    'B4XOM.Keys returns a list of the keys
        Log(B4XOM.values.Get(i))  'B4XOM.Values returns a list of the values
Next
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
My B4XOrderedMap doesn't have the Values membe
You need to download the latest B4XCollections lib ver 1.06 here in post 8
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
You need to download the latest B4XCollections lib ver 1.06 here in post 8

OK, got it now, installed B4XCollections 1.06.
So this is how that nested loop should be then?

B4X:
 For Each oValue As Object In B4XOM.Values
  lstIndexes = oValue
  For c = 0 To lstIndexes.Size - 1
   arrIndex(n) = lstIndexes.Get(c)
   n = n + 1
  Next
 Next

Or is there still something more efficient?

RBS
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
So this is how that nested loop should be then?
Your code is wrong. This is how it should look like. If you are looking for something I do not grasp, good luck. This is my last contribution:
B4X:
Dim lstIndexes As List
    Dim c As Int
    Dim arrIndex(B4XOM.Values.Size) As String
        lstIndexes = B4XOM.Values
        For c = 0 To lstIndexes.Size - 1
            arrIndex(c) = lstIndexes.Get(c)
            Log(lstIndexes.Get(c))
            Log(arrIndex(c))
            Log("-----")            
        Next
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Your code is wrong. This is how it should look like. If you are looking for something I do not grasp, good luck. This is my last contribution:
B4X:
Dim lstIndexes As List
    Dim c As Int
    Dim arrIndex(B4XOM.Values.Size) As String
        lstIndexes = B4XOM.Values
        For c = 0 To lstIndexes.Size - 1
            arrIndex(c) = lstIndexes.Get(c)
            Log(lstIndexes.Get(c))
            Log(arrIndex(c))
            Log("-----")           
        Next

Not sure you are grasping the sorting code. My code works fine and yours won't.
Did you try the full sorting Sub?

RBS
 
Upvote 0
Top