B4J Question How to Unflatten List to a JSON Tree?

Discussion in 'B4J Questions' started by Mashiane, Jun 30, 2019.

  1. Mashiane

    Mashiane Expert Licensed User

    Hi there

    Can anyone please help with a snippet to unflatten data into a json stree?

    For example, this is my list of records...

    Code:
    Dim arr As List
    arr.Initialize
    arr.Add(CreateMap(
    "id":1 ,"parentid" : 0))
    arr.Add(CreateMap(
    "id":4 ,"parentid" : 2))
    arr.Add(CreateMap(
    "id":3 ,"parentid" : 1))
    arr.Add(CreateMap(
    "id":5 ,"parentid" : 0))
    arr.Add(CreateMap(
    "id":6 ,"parentid" : 0))
    arr.Add(CreateMap(
    "id":2 ,"parentid" : 1))
    arr.Add(CreateMap(
    "id":7 ,"parentid" : 4))
    arr.Add(CreateMap(
    "id":8 ,"parentid" : 1))
    To something like...

    Code:
    [
     {
      
    "id"1,
      
    "parentid"0,
      
    "children": [
       {
        
    "id"2,
        
    "parentid"1,
        
    "children": [
         {
          
    "id"4,
          
    "parentid"2,
          
    "children": [
           {
            
    "id"7,
            
    "parentid"4,
            
    "children": []
    ....
    ....
           
    }
     
  2. Brandsum

    Brandsum Active Member Licensed User

    Code:
    Code:
    Dim arr As List
    arr.Initialize
    arr.Add(CreateMap(
    "id":1 ,"parentid" : 0"children"Null))
    arr.Add(CreateMap(
    "id":4 ,"parentid" : 2"children"Null))
    arr.Add(CreateMap(
    "id":3 ,"parentid" : 1"children"Null))
    arr.Add(CreateMap(
    "id":5 ,"parentid" : 0"children"Null))
    arr.Add(CreateMap(
    "id":6 ,"parentid" : 0"children"Null))
    arr.Add(CreateMap(
    "id":2 ,"parentid" : 1"children"Null))
    arr.Add(CreateMap(
    "id":7 ,"parentid" : 4"children"Null))
    arr.Add(CreateMap(
    "id":8 ,"parentid" : 1"children"Null))

    For Each m As Map In arr
        
    For Each mm As Map In arr
            
    If m.get("id") = mm.Get("parentid"Then
                
    Dim l As List
                
    If m.Get("children") = Null Then
                    l.Initialize
                
    Else
                    l = m.Get(
    "children")
                
    End If
                l.Add(mm)
               
                m.put(
    "children",l)
            
    End If
        
    Next
    Next
    Dim finalArr As List:finalArr.Initialize
    For Each m As Map In arr
        
    If m.Get("parentid") = 0 Then finalArr.Add(m)
    Next
       
    Dim json As JSONGenerator
    json.Initialize2(finalArr)
    Log(json.ToPrettyString(4))
    Output:
    Code:
    [
        {
            
    "id"1,
            
    "parentid"0,
            
    "children": [
                {
                    
    "id"3,
                    
    "parentid"1,
                    
    "children"null
                
    },
                {
                    "id": 2,
                    "parentid": 1,
                    "children": [
                        {
                            "id": 4,
                            "parentid": 2,
                            "children": [
                                {
                                    "id": 7,
                                    "parentid": 4,
                                    "children": null
                                }
                            ]
                        }
                    ]
                },
                {
                    "id": 8,
                    "parentid": 1,
                    "children": null
                }
            ]
        },
        {
            "id": 5,
            "parentid": 0,
            "children": null
        },
        {
            "id": 6,
            "parentid": 0,
            "children": null
        }
    ]
     
    Last edited: Jun 30, 2019
    Erel and Mashiane like this.
  3. Mashiane

    Mashiane Expert Licensed User

    @Brandsum Thanks a mill. Managed to follow your logic and rewrote the main script so that I add the 'children' internally within the script

    Code:
    'unflatten as list of map objects using id, parentid, data attributes
    Sub Unflatten(data As ListAs List
        
    'id, parentid, data
        Dim tree As List
        
    Dim mappedArr As Map
        
    '
        tree.Initialize
        mappedArr.Initialize
        
    '
        'create a temp map to hold everything with 'children' as 'data'
        For Each arrElem As Map In data
            
    Dim dID As String = arrElem.Get("id")
            
    '
            Dim children As List
            children.Initialize
            arrElem.Put(
    "data", children)
            
    '
            mappedArr.Put(dID, arrElem)
        
    Next
        
    '
        For Each dID As String In mappedArr.Keys
            
    Dim mappedElem As Map = mappedArr.Get(dID)
            
    Dim parentid As String = mappedElem.Get("parentid")
            
    ' If the element is at the root level, add it to first level elements list.
            If parentid = "" Then
                tree.Add(mappedElem)
            
    Else
                
    'If the element is not at the root level, add it to its parent list of children.
                Dim parentElem As Map = mappedArr.Get(parentid)
                
    Dim children As List = parentElem.Get("data")
                children.Add(mappedElem)
                parentElem.Put(
    "data", children)
                mappedArr.Put(parentid, parentElem)
            
    End If
        
    Next
        
    Return tree
    End Sub
     
    Brandsum likes this.
  4. ThRuST

    ThRuST Well-Known Member Licensed User

    @Mashiane You might want to create an editor for this and share? json usually calls for a simplicity in sight-reading :)
     
  5. Mashiane

    Mashiane Expert Licensed User

    @ThRuST that wouldn’t be an overkill? I needed this for my webix explorations for three of their tree based components to be able to feed data.

    So it’s a tree map to json conversion and there is already a json parser here in b4x.

    If perhaps my plate wasn’t full. I want to finish my html games stuff, and also side projects I’m working on.
     
    ThRuST likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice