Если у меня есть коллекция c
типа T
и есть свойство p
на T
(типа P
, скажем), что это лучший способ , чтобы сделать карту-на-экстрагента-ключ ?
val c: Collection[T]
val m: Map[P, T]
Одним из способов является следующее:
m = new HashMap[P, T]
c foreach { t => m add (t.getP, t) }
Но сейчас мне нужна изменчивая карта. Есть ли лучший способ сделать это так, чтобы он был в 1 строке, и я получил неизменную карту? (Очевидно, я мог бы превратить вышесказанное в простую библиотечную утилиту, как в Java, но я подозреваю, что в Scala нет необходимости)
scala
map
scala-collections
oxbow_lakes
источник
источник
Traversable[K].mapTo( K => V)
иTraversable[V].mapBy( V => K)
были лучше!c
на,c.iterator
чтобы избежать создания промежуточной коллекции.Вы можете создать карту с переменным количеством кортежей. Поэтому используйте метод map в коллекции, чтобы преобразовать его в коллекцию кортежей, а затем используйте трюк: _ *, чтобы преобразовать результат в переменный аргумент.
источник
В дополнение к решению @James Iry, это также можно сделать с помощью сгиба. Я подозреваю, что это решение немного быстрее, чем метод кортежа (создается меньше мусорных объектов):
источник
list.foldLeft(Map[String,Int]()) { (m,s) => m + (s -> s.length) }
. Обратите внимание , что если вы хотите использовать запятую , чтобы построить кортеж, вам требуется дополнительная пара скобок:((s, s.length))
.Это может быть реализовано в неизменном виде и за один проход путем складывания коллекции следующим образом.
Решение работает, потому что добавление в неизменяемую Карту возвращает новую неизменяемую Карту с дополнительной записью, и это значение служит аккумулятором при операции сгиба.
Компромисс здесь - простота кода и его эффективность. Таким образом, для больших коллекций этот подход может быть более подходящим, чем использование двух реализаций обхода, таких как применение
map
иtoMap
.источник
Другое решение (может не работать для всех типов)
это позволяет избежать создания списка посредников, более подробная информация здесь: Scala 2.8 breakOut
источник
То, что вы пытаетесь достичь, немного неопределенно.
Что делать, если два или более элементов в
c
одной и той жеp
? Какой элемент будет сопоставлен с этимp
на карте?Более точный способ взглянуть на это - получить карту между
p
всемиc
предметами, имеющими ее:Это может быть легко достигнуто с groupBy :
Если вы все еще хотите исходную карту, вы можете, например, сопоставить
p
с первой,t
которая имеет ее:источник
collect
вместоmap
. Например:c.group(t => t.p) collect { case (Some(p), ts) => p -> ts.head }
. Таким образом, вы можете делать такие вещи, как сглаживать карты, когда вы нажимаете клавишу Option [_]..mapValues(_.head)
вместо карты.Вероятно, это не самый эффективный способ преобразования списка в карту, но он делает код вызова более читабельным. Я использовал неявные преобразования, чтобы добавить метод mapBy в List:
Пример телефонного кода:
Обратите внимание, что из-за неявного преобразования код вызывающей стороны должен импортировать implicitConversions в scala.
источник
Работает хорошо и очень интуитивно
источник
c
качестве ключа (вроде). Обратите внимание на «карту», потому что результирующая коллекция не является scala,Map
но создает другой список / итерируемый набор кортежей ... но эффект такой же для целей OP, я не стал бы сбрасывать со счетов простоту, но это не так эффективно, какfoldLeft
решение, и не реальный ответ на вопрос «превращение коллекции в карту по ключу»Как насчет использования zip и toMap?
источник
Для чего это стоит, вот два бессмысленных способа сделать это:
источник
Map.fromList $ map (bar &&& id) c
,Map.fromList $ map (bar >>= (,)) c
.Это работает для меня:
Карта должна быть изменяемой, а Карта должна быть возвращена, поскольку добавление в изменяемую Карту не возвращает карту.
источник
val personsMap = persons.foldLeft(Map[Int, PersonDTO]()) { (m, p) => m + (p.id -> p) }
Карта может быть неизменной, как показано выше, потому что добавление к неизменяемой Карте возвращает новую неизменяемую Карту с дополнительной записью. Это значение служит аккумулятором при операции складывания.использовать map () для коллекции с последующей toMap
источник
При преобразовании из Json String (чтение файла JSON) в Scala Map
источник