Android Question How to get the index of an entry in a Map object?

Maps are ideal ways to store data. Retrieving an entry in a Map by using a search phrase is much, much faster than when searching from top to bottom in a long list.
E.g. in a Map with 100.000 entries the Map.contains(Key) function returns results in less than 2 milliseconds!

I have a large dataset that is linked (organize according to) to the index of my Map object (in a huge random access file).
What I need is a way to determine the index of any key/value pair in the Map. There is no Map.GetIndex(Key) function, mainly Map.GetKeyAt(index) and Map.GetValueAt(index).
Who has (or can create) this function?

It would be silly to have to use a loop using: For i = 0 to Map.size - Map.GetKeyAt(index) - next to determine the index of a specific Key/value pair.

PS: I know that in the past using the index functions of a Map has been discouraged, but so far I have always found that items that are transferred from a list to a map land there in the same order and same index as in the list.
 
OK, thanks, but how do I get the index? I need to know where exactly an entry is located in the Map. because that index refers to another, much larger database in an Random Access file. Also I need Key and Value pairs, not only Values, because the Map holds other data too.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Relying on the index in the list is a mistake. You should instead store a custom type with all the information you need.

It is possible to get the internal list with B4XOrderedMap.Keys and then find the index of the key. It will be mush slower as a full scan of the list will be needed each time.
 
Upvote 0
This doesn't really solve my problem. Running through (large) lists from top to bottom is what I am trying to avoid, because it is far too slow.
Isn't there a Javascript or other that can report the index of an item found in an ordinary Map object?
The alternative that I can use is to (once-only) store the index in the Map value for each key, next to other needed data, e.g. separated by a comma or Tab symbol.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Isn't there a Javascript or other that can report the index of an item found in an ordinary Map object?
How is JavaScript related here???????

1708424849610.png
 
Upvote 0

josejad

Expert
Licensed User
Longtime User
because that index refers to another, much larger database in an Random Access file
How about creating a map whose keys are the indexes or your large database?

ie SQL: "SELECT * FROM 'mydatabase' WHERE 'date' >= '2024/02/01'"
You get:
id: 342532, dateRecord: '2024/02/19', name: 'Rick'
id: 342549, dateRecord: '2024/02/20', name: 'Phil'


Create a custom type as Erel suggests, for example
B4X:
Type MyData (id as int, DateRecord As Date, Name As String)
Private dataMap as Map

Then you could create a map with every record, the key would be your record id, and the value your custom data, something like:
dataMap.Put(id, MyData1)
etc...
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
I need to know where exactly an entry is located in the Map. because that index refers to another, much larger database in an Random Access file.

As soon as you remove (or an entry from the Map, all the following entries will move down accordingly, and their indexes will no longer match those of the corresponding records in the Random Access File.

1708436426443.png
 
Upvote 0

emexes

Expert
Licensed User
On a more positive note, if you're not storing the data in a "proper" database (no worries: sounds like you've got legacy data that has to be left in its existing format) then you could store the common lookup fields (Title, Year, Media, CatalogNumber?) in String Arrays, and read them from the Random Access File just once at program startup. For thousands of records stored in a local file, that's usually pretty quick.

For millions of records, or stored in a remote file accessed via the internet, yeah, not quite so quick... perhaps this could be the universe hinting that it's time to move to a database system that will handle that for you. 🤔 Short-term PITA, long-term solution.
 
Upvote 0
As soon as you remove (or an entry from the Map, all the following entries will move down accordingly, and their indexes will no longer match those of the corresponding records in the Random Access File.

View attachment 151027
Thanks, I know, but my Map never gets modified because it is pre-constructed (in a separate app) before using it in my app (in which I simply load the Map with File.ReadMap(File.DirAssets,[Filename]). Over the years I have noted that the index in the map always corresponds to the index in the list from which the Map is originally created (by simply loading all the items in a (sorted) list into the Map and then saving it. All the Map does is serve as an extremely rapid indexer of my huge database.

FYI it is a famous people database with their dates and places of birth (and death) and many other characteristics. Using a MAP (with the Name as Key and the index as value) I can find entries in this 2 Gbyte large database within 2 msecs. Using a list it would take hundreds of msecs, depending on how far down in the list the name of a person is.

I'll leave it at that, thanks.
 
Upvote 0
On a more positive note, if you're not storing the data in a "proper" database (no worries: sounds like you've got legacy data that has to be left in its existing format) then you could store the common lookup fields (Title, Year, Media, CatalogNumber?) in String Arrays, and read them from the Random Access File just once at program startup. For thousands of records stored in a local file, that's usually pretty quick.

For millions of records, or stored in a remote file accessed via the internet, yeah, not quite so quick... perhaps this could be the universe hinting that it's time to move to a database system that will handle that for you. 🤔 Short-term PITA, long-term solution.
Indeed, the database is simply a huge text file with tab delimited items. I am no expert with SQL databases, but so far have never used them much, because of very good experiences using my rapid indexing method using a Map with stored indexes. Maybe I will do a side-by-side speed test some time to compare speeds. I have done speed comparisons between finding entries in Maps and in Lists and the Map solution wins by far every time.
 
Upvote 0
Why not include character 126?
Good question. I forgot to add that I do not use Chr(34) (the '"' sign) because some software gets confused, like the VB6 VSflexgrid Excel-alike object which I also use to construct or modify (CSV-alike) databases in Windows. So it is still 92 characters: Chr(33) to Chr(126) except Chr(34). Characters 0 to 32 nor 127 I also don't use, for obvious reasons. By the way, I also use my "92's methode" to encode (compress) all sorts of data, often using fix-length encoding, thus eliminating the need for Chr(9) tab's or comma's in CSV's. This encoded data can also (partly or fully) be indexes to other Lists or Random Access files holding data.
My method also serves as an encryption method because my databases with all these crazy characters are (almost) impossible to reconstruct.
 
Upvote 0
Top