Android Question B4XOrderedMap sort on values, does it work?

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Working on typing suggestions and need to order on word frequencies and for this I am using a B4XOrderedMap.
The frequencies are the values and the words the key.
Trying to sort on values but can't get it to work:

B4X:
 If mapSuggestionsCounts.Size > 1 Then
  mapSuggestionsCounts.Values.Sort(False)
 End If
 
 For  i = 0 To mapSuggestionsCounts.Size - 1
  Log("GetSuggestions, key: " & mapSuggestionsCounts.Keys.Get(i)  & " - value: " & mapSuggestionsCounts.Values.Get(i))
 Next
 
 For Each iValue In mapSuggestionsCounts.Values
  Log("GetSuggestions, value: " & iValue)
 Next

Gives in the log:

GetSuggestions, key: pat_deprivation - value: 0
GetSuggestions, key: pat_stats - value: 0
GetSuggestions, key: path_points - value: 0
GetSuggestions, key: patient_count - value: 0
GetSuggestions, key: patient_list - value: 0
GetSuggestions, key: patient_type - value: 0
GetSuggestions, key: patient_warnings - value: 0
GetSuggestions, key: patients - value: 3
GetSuggestions, key: patients_points - value: 0
GetSuggestions, key: pats - value: 0

GetSuggestions, value: 0
GetSuggestions, value: 0
GetSuggestions, value: 0
GetSuggestions, value: 0
GetSuggestions, value: 0
GetSuggestions, value: 0
GetSuggestions, value: 0
GetSuggestions, value: 3
GetSuggestions, value: 0
GetSuggestions, value: 0

Keys are string and values are int, so no idea what is going on here.

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
No. Sorting the Values list doesn't change the collection order. Only the order of the Values list that you currently hold.
OK, misunderstood that then.
In that case the syntax is a bit misleading as Keys.Sort does alter the order of the collection.
Also, I am not sure how B4XOrderedMap.Values.Sort works(see testing code), but I made a function
that does sort a B4XOrderedMap(with String keys) by Int values:

B4X:
Sub TestB4XOrderedMapValuesSort

Dim i As Int
Dim OM As B4XOrderedMap
Dim OMSortedOnIntValues As B4XOrderedMap
Dim lstValuesUnSorted As List
Dim lstValuesSorted As List
Dim lstValuesSorted2 As List

OM.Initialize

OM.Put("Key0", 10)
OM.Put("Key1", 2)
OM.Put("Key2", 6)

lstValuesUnSorted = OM.Values

For i = 0 To 2
Log("Before OM.Values.Sort: lstValuesUnSorted.Get(" & i & ")" & lstValuesUnSorted.Get(i))
Next

Log("OM.Values.Sort(True)")
OM.Values.Sort(True)

lstValuesSorted = OM.Values

For i = 0 To 2
Log("After OM.Values.Sort: lstValuesSorted.Get(" & i & ")" & lstValuesSorted.Get(i))
Next

Log("SortB4XOMByIntValues(OM, True)")
OMSortedOnIntValues = SortB4XOMByIntValues(OM,True)

lstValuesSorted2 = OMSortedOnIntValues.Values

For i = 0 To 2
Log("After SortB4XOMByIntValues: " & OMSortedOnIntValues.Keys.Get(i) & ":, lstValuesSorted2.Get(" & i & ")" & lstValuesSorted2.Get(i))
Next

End Sub
Sub SortB4XOMByIntValues(oB4XOM As B4XOrderedMap, bAscending As Boolean) As B4XOrderedMap

Dim i As Int
Dim arrKeys(oB4XOM.Size) As String
Dim arrValues(oB4XOM.Size) As Int
Dim arrIndex() As Int
Dim oB4XOMSorted As B4XOrderedMap

For Each strKey As String In oB4XOM.Keys
arrKeys(i) = strKey
arrValues(i) = oB4XOM.Get(strKey)
i = i + 1
Next

arrIndex = SortOMIntIDX(arrValues, bAscending, -1, -1)

If arrIndex(0) = -1 Then
'all values same, so return old B4XOrderedMap
Return oB4XOM
End If

oB4XOMSorted.Initialize

For i = 0 To arrIndex.Length - 1
oB4XOMSorted.Put(arrKeys(arrIndex(i)), arrValues(arrIndex(i)))
Next

Return oB4XOMSorted

End Sub
Sub Check1DIntAllSame(arrInt() As Int, iStart As Int, iEnd As Int) As Boolean

Dim i As Int
Dim iVal As Int

If arrInt.Length = 1 Then
Return True
End If

If iStart = -1 Then
iStart = 1
End If

If iEnd = -1 Then
iEnd = arrInt.Length - 1
End If

iVal = arrInt(0)

For i = iStart To iEnd
If arrInt(i) <> iVal Then
Return False
End If
Next

Return True

End Sub
Sub SortOMIntIDX(arrInt() As Int, bAscending As Boolean, iStart As Int, iEnd As Int) As Int()
 Dim i As Long
Dim c As Long
Dim n As Long
Dim B4XOM As B4XOrderedMap

If Check1DIntAllSame(arrInt, iStart, iEnd) Then
Dim arrIndex2(1) As Int
arrIndex2(0) = -1
Return arrIndex2
End If

B4XOM.Initialize

If iStart = -1 Then
iStart = 0
End If

If iEnd = -1 Then
iEnd = arrInt.Length - 1
End If

For i = iStart To iEnd
Dim lstIndexes As List
If B4XOM.ContainsKey(arrInt(i)) Then
lstIndexes = B4XOM.Get(arrInt(i))
Else
lstIndexes.Initialize
End If
lstIndexes.Add(i)
B4XOM.Put(arrInt(i), lstIndexes)
Next

B4XOM.Keys.Sort(bAscending)

Dim arrIndex((iEnd - iStart) + 1) As Int

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

Return arrIndex

End Sub

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
It doesn't do anything that will help you.

Use a custom type with fields for all relevant information.
This will allow you to sort the values with Values.SortType.

I know how to sort, no problem with that.
Just wonder now how B4XOrderedMap.Values.Sort could help anybody.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
B4XOrderedMap.Values returns a List. So the list includes all of the List methods. Whether it can be helpful or not is not related.

OK, now I understand! Because it is a list it needs to show the Sort method, although in this case there is no use for it.
Is it not possible to hide methods from the user? If I remember well VBA and VB6 do this.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
OK, now I understand! Because it is a list it needs to show the Sort method, although in this case there is no use for it.
Is it not possible to hide methods from the user? If I remember well VBA and VB6 do this.

RBS
Of course not. It returns a regular List.

I don't know how B4A works behind the scenes, but I meant to hide the Sort method from B4XOrderedMap.Values.
I understand that if you do lst = B4XOrderedMap.Values then lst needs to show the .Sort method.

RBS
 
Upvote 0
Top