Scala - Создание нового списка путем объединения содержимого одного списка и иерархии другого - PullRequest
0 голосов
/ 07 января 2020

Я пытаюсь создать новый список, который объединяет содержимое одного одноуровневого списка с иерархией другого вложенного списка и связывает их по идентификаторам объектов в обоих списках. Примечание: идентификатор объекта BChain хранится в ItemObj внутри него.

У меня есть три объекта:

ItemObj(id: String, stored: DateTime)
BChain(item: ItemObj, List[BChain])
AChain(aid: String, List[AChain])

У меня есть два списка:

val nestedList: List[AChain]
val singleLevelList: List[BChain]

Я хочу, чтобы второй список имел иерархию первого, но все же содержал свои собственные элементы. Следовательно, BChain должен включать исходные свойства ItemObj и List[BChain] (включая все исходные данные свойства ItemObj - ID и DateTime), когда он помещается в новый желаемый вывод списка.

Итак, вместо (ввода):

 val nestedList = List(
 AChain("123", List(AChain("456", [])),
 AChain("789", [])
)

val singleLevelList = List(
 BChain(ItemObj("123", DateTime), []),
 BChain(ItemObj("456", DateTime), []),
 BChain(ItemObj("789", DateTime), []))
)

Я бы хотел следующий вывод:

val combinedLists = List(
     BChain(ItemObj("123", DateTime), List(BChain(ItemObj("456", DateTime), [])),
     BChain(ItemObj("789", DateTime), [])
)

в качестве окончательного списка.

Примечание : Во вложенном списке может быть больше элементов, чем в одноуровневом, и если это так, то дополнительные элементы следует игнорировать. Каждый из элементов одноуровневого списка должен соответствовать одному из элементов во вложенном списке.

Как я могу выполнить sh это?

Буду признателен за любую помощь.

Ответы [ 3 ]

1 голос
/ 07 января 2020

Этот код будет работать, даже если root элемент вложенного списка отсутствует в одноуровневом списке

final case class ItemObj(id: String, stored: DateTime = null)
final case class AChain(aid: String, children: List[AChain] = List())
final case class BChain(bid: ItemObj, children: List[BChain] = List())

val nestedList = List(
  AChain("123", List(AChain("456"))),
  AChain("789")
)

def getCombineList(nestedList: List[AChain], singleList: List[BChain]): List[BChain] = {
  val singleListMap = singleList.groupBy(_.bid.id)

  def combine(items: List[AChain]): List[BChain] = {
    items flatMap {item => 
      val children = combine(item.children)
      val parent = singleListMap.get(item.aid).map(v =>
        List(v.head.copy(children = children))
      ).getOrElse(
        children
      )
      parent
    }
  }

  combine(nestedList)
}

val s = getCombineList(nestedList, List(BChain(ItemObj("456")), BChain(ItemObj("789"))))
1 голос
/ 08 января 2020

Сначала я должен был придумать тип и значение DateTime, чтобы скомпилировать следующее:

case class ItemObj(id: String, stored: DateTime)
case class BChain(item: ItemObj, bcl :List[BChain])
case class AChain(aid: String, acl :List[AChain])

Затем я изменил ваш singleLevelList в реальный код Scala и создал Map для быстрого поиска.

val singleLevelList = List(
  BChain(ItemObj("123", DateTime), Nil),
  BChain(ItemObj("456", DateTime), Nil),
  BChain(ItemObj("789", DateTime), Nil)
)

val sLLMap = singleLevelList.groupBy(_.item.id)

Далее рекурсивный метод для изменения всех AChain с на BChain с.

def a2b(aLst :List[AChain]) :List[BChain] =
  aLst.map(a => BChain(sLLMap(a.aid).head.item, a2b(a.acl)))

Теперь для проверки.

val nestedList = List(
  AChain("123", List(AChain("456", Nil))),
  AChain("789", Nil)
)

a2b(nestedList)  //appears to work

Конечно, это бросит, если nestedList имеет A без соответствующего B в singleLevelList.

1 голос
/ 07 января 2020

Может быть, что-то вроде этого, что вы хотите?

final case class ItemObj(id: String, stored: DateTime)
final case class BChain(item: ItemObj, list: List[BChain])
final case class AChain(aid: String, list: List[AChain])

def combine(as: List[AChain], bs: List[BChain]): List[BChain] = {
  val asMap = as.iterator.map(a => a.aid -> a.list).toMap

  def toBChain(a: AChain): BChain =
    BChain(
      item = ItemObj(id = a.aid, stored = ???),
      list = a.list.map(toBChain)
    )

  bs.map {
    case BChain(item, list) =>
      val newElements =
        asMap
          .getOrElse(key = item.id, default = Nil)
          .map(toBChain)

      BChain(
        item,
        list ::: newElements
      )
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...