Hi,
I have a list which contains only numbers and is never empty, the numbers are also sorted from small to big, but each number might show up more than once, i want to take that list and get a new list that tells me how many times a number has appeared.
For example:
Input: (7,7,7,11,13,13,23)
Output: (3,1,2,1)
Because we had three of 7, and one of 11, and two of 13, and one of 23
Sub FindItemCount(myList As List) As List
Dim result As List
result.Initialize
Dim currentNumber, currentCount As Int
currentNumber = myList.Get(0)
currentCount = 1
For i = 1 To myList.Size - 1
Dim n As Int = myList.Get(i)
If n <> currentNumber Then
result.Add(currentCount)
currentNumber = n
currentCount = 1
Continue
End If
currentCount = currentCount + 1
Next
result.Add(currentCount)
Return result
End Sub
There may be slicker ways of coding this, but here is a suggestion ...
B4X:
Sub subTotal(input As List) As List
Dim output As List
output.Initialize
Dim previous As Int = -1
Dim count As Int = 0
Dim first As Boolean = True
For Each i As Int In input
If (i = previous) Then
count = count + 1
Else
If Not(first) Then
output.Add(count + 1)
count = 0
End If
End If
previous = i
first = False
Next
output.Add(count + 1)
Return output
End Sub
Dim m As Map
m.Initialize
Dim myList As List
myList.Initialize
myList = Array As Int(7,7,7,11,13,13,23)
For Each i As Int In myList
m.Put(i,m.GetDefault(i,0)+1)
Next
For Each k As Int In m.Keys
Log(k & ":" & m.Get(k))
Next
Output:
B4X:
Waiting for debugger to connect...
Program started.
7:3.0
11:1.0
13:2.0
23:1.0
Program terminated (StartMessageLoop was not called).
Doing it this way also eliminates the need for it to be sorted, in case that's useful.
Sub FindItemCount(myList As List) As List
Dim m As B4XOrderedMap = B4XCollections.CreateOrderedMap
For Each i As Int In myList
m.Put(i, m.GetDefault(i, 0) + 1)
Next
Return m.Values
End Sub