Android Question B4XOrderedMap sort error

luke2012

Well-Known Member
Licensed User
Longtime User
Hi all,
I'm implementing a sort using B4XOrderedMap By @Erel (https://www.b4x.com/android/forum/threads/b4x-b4xcollections-more-collections.101071/) and I trying to sort my ordered map using the .SortType method but I got an error:

Error occurred on line: 61 (B4XOrderedMap)
java.lang.NoSuchFieldException: No field created in class Lanywheresoftware/b4a/objects/collections/Map$MyMap; (declaration of 'anywheresoftware.b4a.objects.collections.Map$MyMap' appears in base.apk)

Note: "created" is a field that a putted within the ordered map values before call it.
Is it probably my mistake?
See the relevant code:

B4X:
'Class clsGlobals
Sub Class_Globals
         Public FIELD_ART_CDATE As String = "created"
         '......
end sub
Sub GetArtContent (nid As Int, aUser As String, aPsw As String) As ResumableSub
    Try
 
        'I got the putted values from a json parsing and all the values are putted and populated correctly
        Dim field_image As List = JRoot.Get("field_image") '>>> img attachment is madatory so is always available
        For Each colfield_image As Map In field_image
            Private mapContent As Map
            mapContent.Initialize
            Dim target_id As Int = colfield_image.Get("target_id")  
            Dim alt As String = colfield_image.Get("alt")          
            Dim ArtImgtitle As String = colfield_image.Get("title")     
            Dim imgURL As String = colfield_image.Get("url")  
            Dim artNID As Int = nid
            mapContent.Put (FIELD_ART_NID, artNID)          
            mapContent.Put (FIELD_ART_TITLE, ArtTitle)      
            mapContent.Put (FIELD_ART_BODY, ArtBody)      
            mapContent.Put (FIELD_ART_IMG_ID, target_id) 
            mapContent.Put (FIELD_ART_IMG_ALT, alt)
            mapContent.Put(FIELD_ART_IMG_TITLE, ArtImgtitle)     
            mapContent.Put(FIELD_ART_IMAGE_URL, imgURL)
            'download image
            Wait For (DownloadImage(imgURL)) Complete (Image As Bitmap)
            mapContent.Put (FIELD_ART_IMAGE, Image)
            mapContent.Put (FIELD_ART_CDATE, CDate) 'creation date
            mapArtIMGs.Put(target_id, mapContent)
        Next
     
        Log("")
             
    Catch
        'Log ...
    End Try
     
    Return mapArtIMGs
end sub

Sub imgNews_Click
    Wait For (AppGlobals.GetArtsNIDs (AppGlobals.user, AppGlobals.psw)) Complete (ArtsNIDs As B4XOrderedMap)
    For Each nid As Int In ArtsNIDs.Keys
        Wait For (AppGlobals.GetArtContent (nid, AppGlobals.user, AppGlobals.psw)) Complete (ArtContent As B4XOrderedMap)
    Next
ArtContent.Values.SortType (AppGlobals.FIELD_ART_CDATE, True)
end sub
 

luke2012

Well-Known Member
Licensed User
Longtime User
1. Sorting the values will not affect the B4XOrderedMap order. The keys define the order.
2. You are adding maps as the values. List.SortType works with custom types.

Hi Erel, thanks for the explanation.
So the possible solutions in order to sort my "ArtContent" B4XOrderedMap by cdate field are (?):

1) Instead of map (mapContent As Map) have I to use a type as B4XOrderedMap value ?

2) If the 1) solution doesn't work the only solution is to male the cdate field as a time stamp and use as B4XOrderedMap key?
In this case I can sort the B4XOrderedMap by date (timestamp) ?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
We need more information in order to answer these questions.

Why are you using a map instead of a regular list? What is the collection approximate size?

Why do you need to sort the items? You can add custom types as values and sort the values list. The values list is a copy of the internal data. It will not affect the map collection.
 
Upvote 0

luke2012

Well-Known Member
Licensed User
Longtime User
We need more information in order to answer these questions.

Why are you using a map instead of a regular list? What is the collection approximate size?

Why do you need to sort the items? You can add custom types as values and sort the values list. The values list is a copy of the internal data. It will not affect the map collection.

I try to response to your questions:
1) "Why do you need to sort the items?"
I need to sort the items because these items represent articles (news) that must be sorted by creation date (the newest ones at the top and the oldest ones at the bottom of the clv I'm going to create).

2) "Why are you using a map instead of a regular list?"
I am using a map because it allows me to have unique id as key to retrieve the articles via a .Get (ArtNID).
Each article is a drupal article that have its own id that I need to keep and use to retrieve and idetify the (drupal) articles.

In conclusion, I would need a data structure that allows me to have all these items sorted by creation date and also have the way (when needed) to retrieve them by the unique id of the article (see artNID ---> article drupal node id).

Thank for your help.
Very appreciated.
Luca.
 
Upvote 0

luke2012

Well-Known Member
Licensed User
Longtime User
Use a list with custom types. Sort it however you want and get the items with:
B4X:
Sub GetItem (id As String) YourType
For Each yt As YourType In YourList
  If yt.Id = id Then Return yt
Next
Return Null
End Sub
It will be very fast.

Thanks for suggestion. I'll try to implement it.

Just to my knowledge, if instead I use a B4XOrderedMap and a type as value, and I execute the .Values.SortType (fieldname, true) method of the B4XOrderedMap will the map be sorted by the specified field?
 
Upvote 0

luke2012

Well-Known Member
Licensed User
Longtime User
Each call to B4XOrderedMap.Values return a new list with the values. You can sort it however you like, however it will only affect the current values list that you are holding.

"return a new list with the values" and "however it will only affect the current values list"

I can still sort the list that returns me .values but even if I order it the main map (in my case a B4XOrderedMap) which contains the values will not be sorted correctly?

Assuming that the values are entered as types, it would have been great if the B4XOrderedMap had a method that would sort the map by passing a field name contained in the map values and consequently the related map keys would also be sorted.
 
Last edited:
Upvote 0
Top