Подтвердить что ты не робот

Преобразование карты Scala в список

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

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.

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

Спасибо заранее.

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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