Android Question (solved) comparing 2 lists

edm68

Member
Licensed User
Longtime User
Hi,
I can't figure out what's wrong with my logic.
I have 2 lists, one with values 1 thru 6 (lstAll), the other with 1,6,3 (lstSelected).
I'm trying to compare the two lists and remove the items that are in lstSelected from lstAll.
I'm not very good at explaining so here's what I have. Any help would be appreciated.
Thanks.

B4X:
Sub Globals
    Private lstAll,lstSelected As List
End Sub

Sub Activity_Create(FirstTime As Boolean)
    lstAll.Initialize
    lstSelected.Initialize
    For i=1 To 6
        lstAll.Add(i)
    Next
    lstSelected.Add(1)
    lstSelected.Add(6)
    lstSelected.Add(3)
    Log("lstAll= " & lstAll)
    Log("lstSelected= " & lstSelected)
    compareLists

Sub compareLists
   Dim intI,intJ As Int
   Dim lstTemp As List
   lstTemp.Initialize
   lstTemp=lstAll
   Log("lstTemp= " & lstTemp)
   For i=0 To lstTemp.Size-1
       Log("i= " & i & "******")
       Log("lstTemp.size= " & lstTemp.Size)
       intI=lstTemp.Get(i)
       Log("intI= " & intI)
       For j=0 To lstSelected.Size-1
           intJ=lstSelected.Get(j)   ':Log(strJ)
           If intI=intJ Then
               lstAll.RemoveAt(i) 
               Log("lstAll= " & lstAll)
               Log("lstTemp= " & lstTemp)
               Exit
           End If
       Next
   Next
End Sub

edit: forgot to include error:
main_comparelists (java line: 411)
java.lang.IndexOutOfBoundsException: Index: 4, Size: 3
at java.util.ArrayList.get(ArrayList.java:411)
at anywheresoftware.b4a.objects.collections.List.Get(List.java:117)
at b4a.comparelists.main._comparelists(main.java:411)
at b4a.comparelists.main._activity_create(main.java:368)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:191)
at b4a.comparelists.main.afterFirstLayout(main.java:104)
at b4a.comparelists.main.access$000(main.java:17)
at b4a.comparelists.main$WaitForLayout.run(main.java:82)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6316)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
When removing items from a list you need to traverse it backwards, otherwise when you remove items the list gets shorter and you end up looking for items in indexes that no longer exist.

Although you could also use the List.IndexOf method :

B4X:
For Each i As int In lstSelected
    Dim Pos As Int = lstAll.indexOf(i)
    If Pos > -1 Then lstAll.RemoveAt(Pos)
Next

This will only work if the values in the list you are searching are of the same type you are searching for i.e. Int in this case.
 
Last edited:
Upvote 0

edm68

Member
Licensed User
Longtime User
Hi, thanks stevel05 for your reply.
I guess I thought when I added lstTemp in the sub compareLists and made it equal to lstAll, it would subtract from lstAll & not lstTemp?
Hope that makes sense. I don't understand why lstTemp gets shorter as well?

Will definitely look into the List.IndexOf method tomorrow.

Thanks again.
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
I can see what you tried to do, but copying a list using an assignment (lstTemp=lstAll) only creates a pointer to the original list, so you are effectively using the same list.
You would need to 'clone' the list by adding the items in the first list to the second, then you would have two separate lists.
 
Upvote 0

edm68

Member
Licensed User
Longtime User
I understand now. I didn't realize about the pointer.
Your code works perfectly and is only 4 lines. Looks so much better.
Thanks very much.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is possible that you actually need a set instead of a list. You can use a map as a set by just using the keys.

B4X:
Dim AllValues As Map
AllValues.Initialize
For i = 1 To 6
 AllValues.Put(i, "")
Next
Dim Selected As Map = CreateMap(1: "", 3: "")
For Each SelectedNumber As Int In Selected.Keys
 AllValues.Remove(SelectedNumber)
Next
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Or you can use just a single map, marking each value as "valid" or "not valid".
 
Upvote 0
Top