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: 103

JohnC

Expert
Licensed User
Longtime User
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

zmrcic

Member
Licensed User
Longtime User
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

emexes

Expert
Licensed User
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

zmrcic

Member
Licensed User
Longtime User
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

DonManfred

Expert
Licensed User
Longtime User
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

Spavlyuk

Active Member
Licensed User
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.

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

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

Daestrum

Expert
Licensed User
Longtime User
Slight typo in the above code
B4X:
return "x=" & X & "; y=" & Y;  // b4x uses &

B4X:
return "x=" + X + "; y=" + Y;
 
Upvote 0

Brian Dean

Well-Known Member
Licensed User
Longtime User
. . . 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

MicroDrie

Well-Known Member
Licensed User
Longtime User
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

Brian Dean

Well-Known Member
Licensed User
Longtime User
. . . 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
Top