Инвертирование карты в Скале - PullRequest
0 голосов
/ 27 июня 2018

Я делаю курс в Coursera о функциональном программировании Scala. Я на 6 неделе.

У меня есть следующий код:

/* define the map of numbers to letters */ 
val nmem = Map(
  '2' -> "ABC", '3' -> "DEF", '4' -> "GHI", '5' -> "JKL", 
  '6' -> "MNO", '7' -> "PQRS", '8' -> "TUV", '9' -> "WXYZ"
)

/* invert the map to get a map of letters to digits */
val charCode: Map[Char, Char] = 
  for {
       (digit, str) <- nmem
       ltr <- str
  } yield ltr -> digit

Мой вопрос: как работает понимание? nmem вводит ключ (символ) и значение (строку) в цифру и стр. И позже у нас есть: ltr <- str, который я не знаю, как он работает, потому что я не понимаю, как программа знает, что ltr это символ вместо строки. </p>

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

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Синтаксис item <- collection обычно используется для итерации каждого элемента в коллекции.

Простой пример:

for(mapping <- map){
   println(mapping)
}

В вашем случае это, по сути, вложенный цикл for, использующий синтаксис yield.

По умолчанию он создает List и накапливает все элементы.

Написано с немного большим синтаксисом может помочь:

val charCode : Map[Char,Char] = {  // Cast our result to a Map of (Char, Char)
    for ((digit, str) <- nmem;     // for every key-value pair (Char, String) in nmem
         ltr <- str)               // for every ltr (Char) in str (String)
    yield ltr -> digit             // add a new mapping to the map
}

Вы можете проверить https://docs.scala -lang.org /../ for-compthonsions.html для получения более подробной информации

0 голосов
/ 27 июня 2018

Это for -понимание разбито на

nmem.flatMap { case (digit, str) => str.map { ltr => (ltr, digit) } }

Поскольку nmem имеет тип Map[Char, String], компилятор знает, что (digit, str) должен иметь тип (Char, String). Таким образом, он знает, что str имеет тип String. Элементы String имеют тип Char, таким образом, тип ltr выводится как Char.

Если бы вы хотели записать все кровавые детали вывода типа, вы бы получили что-то вроде этого:

nmem.flatMap[(Char, Char), Map[Char, Char]]{ 
  case (digit: Char, str: String) => 
  str.map[(Char, Char), Seq[(Char, Char)]]{ 
    (ltr: Char) => (ltr, digit) 
  } 
}

К счастью, в этом нет необходимости, поскольку все эти типы могут быть выведены автоматически.

0 голосов
/ 27 июня 2018

Первый фактически (digit, str) <- nmem, получает один кортеж из Map [String, String], а следующий ltr <- str получает символы из этой строки.

...