Преобразование карты Scala в список - PullRequest
28 голосов
/ 09 августа 2011

У меня есть карта, которую нужно сопоставить с другим типом, и результатом должен быть список.У меня есть два способа (казалось бы) выполнить то, что я хочу, поскольку вызов карты на карте, кажется, всегда приводит к карте.Предполагая, что у меня есть какая-то карта, которая выглядит следующим образом:

val input = Map[String, List[Int]]("rk1" -> List(1,2,3), "rk2" -> List(4,5,6))

Я могу сделать:

val output = input.map{ case(k,v) => (k.getBytes, v) } toList

Или:

val output = input.foldRight(List[Pair[Array[Byte], List[Int]]]()){ (el, res) =>
  (el._1.getBytes, el._2) :: res
}

В первом примере я конвертируювведите, а затем вызовите toList.Я предполагаю, что время выполнения - что-то вроде O(n*2), а необходимое пространство - n*2.Во втором примере я конвертирую тип и генерирую список за один раз.Я предполагаю, что время выполнения равно O(n), а требуемое пространство равно n.

Мой вопрос: они практически идентичны или второе преобразование сокращает память / время / и т. Д.?Кроме того, где можно найти информацию о стоимости хранения и времени выполнения различных преобразований scala?

Заранее спасибо.

Ответы [ 2 ]

27 голосов
/ 09 августа 2011

Мой любимый способ сделать такие вещи - это:

input.map { case (k,v) => (k.getBytes, v) }(collection.breakOut): List[(Array[Byte], List[Int])]

С этим синтаксисом вы переходите к map строителю, который необходим для восстановления результирующей коллекции.(На самом деле, не сборщик, а фабрика сборщиков. Подробнее о CanBuildFrom s в Scala можно узнать, если вам интересно.) collection.breakOut может быть точно использован, когда вы хотите переключиться с одного типа коллекции на другой при выполнении map, flatMap и т. Д. - единственная плохая часть заключается в том, что для того, чтобы оно было эффективным, необходимо использовать аннотацию полного типа (здесь я использовал типовое обозначение после выражения).Затем промежуточная коллекция не создается, а список создается при отображении .

24 голосов
/ 09 августа 2011

Отображение вида в первом примере может сократить потребность в пространстве для большой карты:

val output = input.view.map{ case(k,v) => (k.getBytes, v) } toList
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...