Android Question B4XSet from Single Items List Eliminates Duplicates But B4XSet from a List of Arrays Does Not

Mahares

Expert
Licensed User
Longtime User
B4X:
'Below using a list of individul items. It eliminates duplicates:
    MyList.Add("1500,De 1x46,-2.5")
    MyList.Add("1000,De 1x8,-4")
    MyList.Add("500,De 1x32,-2.5")
    MyList.Add("500,De 1x32,-2.5")
    MyList.Add("2013,DE 1x17,27")

    Dim b4xs As B4XSet = B4XCollections.CreateSet
    For Each objItem As String In MyList
        b4xs.Add(objItem)
    Next
Log(b4xs.aslist.Size)  'displays: 4

B4X:
'Below using a list of arrays. Does not eliminate duplicates:
    MyList.Add(Array As String(1500,"De 1x46",-2.5))
    MyList.Add(Array As String(1000,"De 1x8",-4))
    MyList.Add(Array As String(500,"De 1x32",-2.5))
    MyList.Add(Array As String(500,"De 1x32",-2.5))
    MyList.Add(Array As String(2013,"DE 1x17",27))    

    Dim b4xs As B4XSet = B4XCollections.CreateSet
    For Each objItem() As String In MyList
        b4xs.Add(objItem)
    Next
Log(b4xs.aslist.Size) 'displays: 5
I am wondering why. Thank you for a sliver of help.
 

PaulMeuris

Well-Known Member
Licensed User
B4X:
    'Below using a list of individual items. It eliminates duplicates:
    MyList.Add("1500,De 1x46,-2.5")
    MyList.Add("1000,De 1x8,-4")
    MyList.Add("500,De 1x32,-2.5")
    MyList.Add("500,De 1x32,-2.5")
    MyList.Add("2013,DE 1x17,27")

    Dim b4xs As B4XSet = B4XCollections.CreateSet
    For Each objItem As String In MyList
        b4xs.Add(objItem)
    Next
    Log(b4xs.aslist.Size)  'displays: 4
    MyList.Clear
    'Below using a list of arrays. Does not eliminate duplicates:
    MyList.Add(Array As String(1500,"De 1x46",-2.5))
    MyList.Add(Array As String(1000,"De 1x8",-4))
    MyList.Add(Array As String(500,"De 1x32",-2.5))
    MyList.Add(Array As String(500,"De 1x32",-2.5))
    MyList.Add(Array As String(2013,"DE 1x17",27))

    Dim b4xs As B4XSet = B4XCollections.CreateSet
    For Each objItem2() As String In MyList
        b4xs.Add(objItem2(0) & "," & objItem2(1) & "," & objItem2(2))
    Next
    Log(b4xs.aslist.Size) 'displays: 4 !
    For i = 0 To b4xs.Size -1
        Log(b4xs.AsList.Get(i))
    Next
4
4
1500,De 1x46,-2.5
1000,De 1x8,-4
500,De 1x32,-2.5
2013,DE 1x17,27
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
b4xs.Add(objItem2(0) & "," & objItem2(1) & "," & objItem2(2))
By concatenating all elements into one string like you have it, you are converting it back to the first type of list which works. Can it it be done without converting the list of arrays to a list of individual items.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
After reviewing the library code and since a B4XSet is derived from a list of keys of an orderedmap which is in turn derived from a map, I do not think it is possible to use a list of array of strings and be able to remove duplicates. That is why my first list code works and the second does not. But, I will wait for a confirmation to corroborate what I was thinking or show me it is possible.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is related to the way the underlying JVM compares the specific type of object. Arrays are compared by their identity. If you convert the arrays to lists then it will actually compare them based on their content and it will work as you expect:
B4X:
Sub AppStart (Args() As String)
    Log("Hello world!!!")
    Dim MyList As List
    MyList.Initialize
    MyList.Add(ToList(Array As String(1500,"De 1x46",-2.5)))
    MyList.Add(ToList(Array As String(1000,"De 1x8",-4)))
    MyList.Add(ToList(Array As String(500,"De 1x32",-2.5)))
    MyList.Add(ToList(Array As String(500,"De 1x32",-2.5)))
    MyList.Add(ToList(Array As String(2013,"DE 1x17",27)))

    Dim b4xs As B4XSet = B4XCollections.CreateSet
    For Each objItem As Object In MyList
        b4xs.Add(objItem)
    Next
    Log(b4xs.aslist.Size) 
End Sub

Private Sub ToList(arr As List) As List
    Return arr
End Sub
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
If you convert the arrays to lists
B4X:
    MyList.Add((Array As String(1500,"De 1x46",-2.5)).As(List))
    MyList.Add((Array As String(1000,"De 1x8",-4)).As(List))
    MyList.Add((Array As String(500,"De 1x32",-2.5)).As(List))
    MyList.Add((Array As String(500,"De 1x32",-2.5)).As(List))
    MyList.Add((Array As String(2013,"DE 1x17",27)).As(List))

Without Sub ToList?
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Both Erel's and Mario's work well (@LucaMs gets nervous when I call him Mario).
To display the B4XSet data and append to a SQLite table, I use this:
B4X:
strQuery="INSERT INTO Crossfalls VALUES(?, ?, ?)"
For i =0 To b4xs.Size-1
        Dim l As List = b4xs.AsList.Get(i)
        SQL.ExecNonQuery2(strQuery, l)
        For Each s As String In l
            Log(s)
        Next   
    Next
The reason I wanted to pursue B4XSet is that you can have a table without a composite PRIMARY KEY and still insure that your data will not contain duplicate rows. That's the power of B4XSet.
 
Upvote 0
Top