2015-08-20 18 views
6

sto avendo l'elenco degli oggetti con il bambino genitore di riferimentoNon in grado di creare oggetti annidati in Scala

case class EmployeeLevel(id: Long, name: String, parentId: Long, 
         item: List[EmployeeLevel]) 

val employeeList = List(
    EmployeeLevel(1L, "Manoj", 0L, Nil), 
    EmployeeLevel(2L, "Sv", 1L, Nil), 
    EmployeeLevel(3L, "Cp", 2L, Nil), 
    EmployeeLevel(4L, "Manju", 3L, Nil)) 

Come creare struttura ad albero o disporle in un ordine gerarchico come

val employeeList = List(
    EmployeeLevel(1L, "Manoj", 0L, List(
    EmployeeLevel(2L, "Sv", 1L, List(
     EmployeeLevel(3L, "Cp", 2L, List(
     EmployeeLevel(4L, "Manju", 3L, Nil)))))))) 

o questo è il jSON finale che dovrei ottenere

[ 
    { 
     "id": 1, 
     "name": "Manoj", 
     "parentId": 0, 
     "item": [ 
      { 
       "id": 2, 
       "name": "Sv", 
       "parentId": 1, 
       "item": [ 
        { 
         "id": 3, 
         "name": "Cp", 
         "parentId": 2, 
         "item": [ 
          { 
           "id": 4, 
           "name": "Manju", 
           "parentId": 3, 
           "item": [ ]       

          } 
         ] 
        } 
       ] 
      } 
     ] 
    } 
] 

ho provato con questo:

def arrange(employee1:List[EmployeeLevel],accumulator:List[EmployeeLevel]): List[EmployeeLevel] ={ 
    @tailrec def arrange1(employeeLevel:List[EmployeeLevel],accu:List[EmployeeLevel]):List[EmployeeLevel] ={ 
     if(employeeLevel.nonEmpty){ 
     val headd=employeeLevel.head 
     val taill=employeeLevel.tail 
     val tt=taill.filter(_.parentId==headd.id) 
     val qq= List(headd.copy(item = tt)) 
     arrange1(taill,accu++qq) 
     }else{ 
     accu 
     } 

    } 
    arrange1(employee1,Nil) 
    } 

Ma il suo lavoro per un solo livello

+1

Sarebbe bello aggiungere ciò che si' ho già provato, o sembrerà una domanda "come lo faresti per me". – cchantep

+0

Il codice che hai postato sembra soddisfacente. Qual è il problema? –

+1

voglio ottenere il risultato richiesto utilizzando la funzione ricorsione o riduzione. – cpawali

risposta

5

Questo dovrebbe fare il trucco

object App { 
    case class EmployeeLevel(id: Long, name: String, parentId: Long, 
    item: List[EmployeeLevel]) 

    val employeeList = List(
    EmployeeLevel(1L, "Manoj", 0L, Nil), 
    EmployeeLevel(2L, "Sv", 1L, Nil), 
    EmployeeLevel(3L, "Cp", 2L, Nil), 
    EmployeeLevel(4L, "Manju", 3L, Nil), 
    EmployeeLevel(5L, "foobar", 2L, Nil), 
    EmployeeLevel(6L, "barfoo", 42L, Nil)) 

    def main(args : Array[String]) { 
    val nestedEmployees = createNestedEmployeesList(employeeList) 

    println(nestedEmployees) 
    } 

    def createNestedEmployeesList(employees: List[EmployeeLevel]): Iterable[EmployeeLevel] = { 
    val children = employees.groupBy(_.parentId) 

    val rootNodes = findRootNodes(employees) 

    rootNodes.flatMap(createChildrenList(_, children)) 
    } 

    def createChildrenList(id: Long, children: Map[Long, List[EmployeeLevel]]): List[EmployeeLevel] = { 
    children.get(id) match { 
     case Some(employees) => 
     employees.map(employee => employee.copy(item = createChildrenList(employee.id, children))) 
     case None => Nil 
    } 
    } 

    def findRootNodes(employees: List[EmployeeLevel]): Set[Long] = { 
    val parentIds = employees.map(_.parentId).toSet 
    val nodeIds = employees.map(_.id).toSet 

    parentIds &~ nodeIds 
    } 
} 

L'algoritmo fornisce il seguente output

List(EmployeeLevel(1,Manoj,0,List(EmployeeLevel(2,Sv,1,List(EmployeeLevel(3,Cp,2,List(EmployeeLevel(4,Manju,3,List()))), EmployeeLevel(5,foobar,2,List())))))) 
+0

Funziona solo se tutti i dipendenti hanno un antenato comune ('0L' in questo caso). Se ci sono più nodi radice, si perderanno alcuni dipendenti. È possibile definire una funzione 'findRoots', filtrare l'elenco dei dipendenti, applicare la' createChildrenList' a ogni nodo radice e quindi appiattire i risultati. – Marth

+0

Grazie. Funziona bene e nel mio caso il genitore di base avrà l'id genitore 0L – cpawali

+0

Grazie a @Marth, hai ragione. Ho aggiornato la mia soluzione anche per il caso generale :-) –

Problemi correlati