Android Question does List contains Map

zmrcic

Member
Licensed User
Longtime User
I have a List of Maps, Maps are simple points, like (x,y)
I'm trying to check if the first list contains elements(maps) from the second list...
B4X:
For i=0 To oList.Size -1
        Dim m As Map=oList.Get(i)
        startX= m.Get("x")
        Log("X1:" & startX)
        startY= m.Get("y")
        Log("Y1:" & startY)
        
        Dim x2 As Map=oArticles.Get(1)
        Log("X2:" & x2.Get("x"))
        Log("Y2:" & x2.Get("y"))
        Log(oArticles.IndexOf(m))

but I always get -1 as an index, even Maps are simple structures, just two integers, x and y
result, log, is on image
 

Attachments

  • listmap.png
    listmap.png
    22.3 KB · Views: 571
ChatGPT says...

When you attempt to find a map within a list of maps using IndexOf, it checks for the exact same map object in memory, not just an identical structure. If m is not the exact same object instance as one in oArticles, IndexOf will return -1, indicating the object was not found, even if there are maps with the same "x" and "y" values.

To check if a map with the same "x" and "y" values exists in oArticles, you need to manually iterate through oArticles and compare the "x" and "y" values of each map to those of m. Here's how you can do it:

B4X:
For i = 0 To oList.Size - 1
    Dim m As Map = oList.Get(i)
    Dim startX As Int = m.Get("x")
    Log("X1:" & startX)
    Dim startY As Int = m.Get("y")
    Log("Y1:" & startY)
   
    Dim found As Boolean = False
    For j = 0 To oArticles.Size - 1
        Dim x2 As Map = oArticles.Get(j)
        Dim x2Value As Int = x2.Get("x")
        Dim y2Value As Int = x2.Get("y")
        Log("X2:" & x2Value)
        Log("Y2:" & y2Value)
       
        If startX = x2Value And startY = y2Value Then
            Log("Found at index: " & j)
            found = True
            Exit ' Exit the loop once a match is found
        End If
    Next
    If Not(found) Then
        Log("Not found")
    End If
Next
This code snippet iterates through each map in oList and then checks every map in oArticles to see if there is a match based on the "x" and "y" values. When a match is found, it logs the index of the found map in oArticles and exits the inner loop to avoid unnecessary comparisons.
 
Upvote 0
thanks
well, it is working in Visual Studio, so I don't know about chatGPT.
off course I can iterate over lists, all three lists contain>1000 points used for drawing....so it is not a solution.
I guess I will have to change API that returns drawing points, so instead of simple X and Y, I will add a third member, Contains(true or false) and check that in VS code(or something like that).

I will wait for Erel confirmation, maybe he knows some workaround :)
 
Upvote 0
I will wait for Erel confirmation
It will help to know:
- what type are the coordinates? (eg Byte, Short, Int, Long, Float or Double)
- what are the minimum and maximum coordinate values? (eg X is 0 to 639, Y is 0 to 479)
- do you only need exact matches, or is it going to change to nearest match?
- if nearest match: is Manhattan distance ok, or does it have to be true (Pythagorean) distance?
 
Last edited:
Upvote 0
I have changed API that sends coordinates, so now I have
B4X:
 {
 "x": 12,
 "y": 6,
 "toDraw": 0,
 "isArticle": 1
 },
 {
 "x": 12,
 "y": 5,
 "toDraw": 1,
 "isArticle": 0
 },

this solved my problem, like "isArticle": 1, means that list oArticles contains map from original list, oList.
but still, it should be nice if there were something like contains in B4X.
 
Upvote 0
b4X iterates though thousand items in a list really fast.

it may be relevant with millions of datasets. But with this a list becomes the wrong solution if you can not hold all the items in memory and you should better use a database to hold them all.

It may be easier to search or limit the database-results with a SQL-Query
B4X:
WHERE isArticle=1
too.
 
Upvote 0
off course I can iterate over lists, all three lists contain>1000 points used for drawing....so it is not a solution.
IndexOf also iterates over the entire list, it's not like you'd avoid iteration that way. And the reason it returns -1 was explained in the first answer, each map you create is different, even if each property has the same value. If you want easy comparisons between such objects, you can create a class such as the following.

[CODE lang="b4x" title="MyPoint.bas"]Sub Class_Globals
Private X As Int
Private Y As Int
End Sub

Public Sub getX As Int
Return X
End Sub

Public Sub getY As Int
Return Y
End Sub

Public Sub Initialize(X1 As Int, Y1 As Int)
X = X1
Y = Y1
End Sub

#If JAVA
@Override
public String toString() {
return "x=" & X & "; y=" & Y;
}

@Override
public boolean equals(Object other) {
if (!(other instanceof mypoint)) { return false; }
return _x.equals(((mypoint)other)._x) && _y.equals(((mypoint)other)._y);
}
#End If[/CODE]

Afterwards, you can compare if 2 instances of a MyPoint are equal without explicitly checking each property and IndexOf should also work properly.
 
Upvote 0
Slight typo in the above code
Code:
return "x=" & X & "; y=" & Y;  // b4x uses &

Code:
return "x=" + X + "; y=" + Y;
 
Upvote 0
. . . but still, it should be nice if there were something like contains in B4X.

Here is the definition of Contains in VB (from Google) :

Contains returns True if the collection contains an element with a key exactly matching Key . Otherwise, Contains returns False .

Is this not the same as the B4X Map.ContainsKey? Have I missed something?
 
Upvote 0
Here is the definition of Contains in VB (from Google) :

Is this not the same as the B4X Map.ContainsKey? Have I missed something?
To answer your last question: I think you missed the answer to post #6 from DonManfred. Because what is leading here, the goal or a specific means which you have been warned that that approach is not scalable if you want to do it like VB does?
 
Upvote 0
. . . that approach is not scalable if you want to do it like VB does?
Hi @MicroDrie . You might be right - I did not realise from the OP's first post that it was the quantity of map objects that was the root of this problem. I still have a feeling that the real problem was that the OP thought that he was comparing map contents when he was actually comparing map pointers, as ChatGPT explained quite correctly in post#2.
 
Upvote 0
Back
Top