#scala
Вопрос:
У меня есть список имен файлов, и я хочу загружать соответствующие страницы пакетами (а не все сразу). Для этого я использую FoldLeft
и пишу агрегатную функцию, которая агрегирует будущую[Карту[T1,T2]].
def loadPagesInBatches[T1, T2](fileNames: Set[FileName]): Future[Map[T1, T2]] = {
val fileNameToPageId: Map[FileName, PageId] = ... //invokes a function that returns the pageId correlated to the fileName.
val batches: Iterator[Set[FileName]] = fileNames.grouped(10) //batches of 10;
batches.foldLeft(Future(Map.empty[T1, T2]))(aggregate(fileNameToPageId))
}
И подпись aggregate выглядит следующим образом:
def aggregate(fileNameToPageId: Map[FileName, PageId]): (Future[Map[T1, T2]], Set[FileName]) => Future[Map[T1, T2]] = {..}
Я пытаюсь убедиться, что это лучший способ объединить эти будущие[Карты].
Заранее спасибо!
P. S: FileName
и PageId
это просто типы строк.
Ответ №1:
В случае, если у вас есть ровно 2 варианта будущего, это, zipWith
вероятно, будет наиболее идиоматичным.
val future1 = ???
val future2 = ???
future1.zipWith(future2)(_ _)
Что является более коротким способом написания а для понимания:
for {
map1 <- future1
map2 <- future2
} yield map1 map2
Хотя zipWith
потенциально может быть реализована какая-то оптимизация.
Комментарии:
1. Но у меня есть более 2 карт. Допустим, у меня есть 100 файлов, и я беру пакеты по 10. Это будет означать, что у меня есть 10 карт из этих пакетов и 1 пустая карта, с которой я начинаю в
reduceLeft
функции.2. У меня есть только две карты в моей подфункции, если вы это имели в виду.
3. Да, я имею в виду, если у вас есть 2
Future[Map[A,B]]
локально в вашей функции.4. Спасибо. Первый вариант действительно работает (второй-нет; вероятно, потому, что map2 не в моем понимании, как вы можете видеть в моем решении).
Ответ №2:
Мое решение состояло в том, чтобы поместить две карты в список и использовать Future.reduceLeft
.
def aggregate(fileNameToPageId: Map[FileName, PageId]): (Future[Map[T1, T2]], Set[FileName]) => Future[Map[T1, T2]] = {
case (all, filesBatch) =>
val mapOfPages: Future[Map[NodeId, T]] = for {
... //Some logic
} yield "TheBatchMap"
Future.reduceLeft(List(all, mapOfPages))(_ _)
}