Для понимания с помощью поиска по карте - есть ли лучший способ?

Рассмотрим следующие

val myMap: Map[String, List[Int]] = Map("a" -> List(1,2,3), 
                                        "b" -> List(4,5,6), 
                                        "d" -> List(7))

val possibleKeys: List[String] = List("c","a", "b", "e")

Я хотел бы пройти по возможным ключам, и если карта содержит один, пройти по значениям карты

Я придумал следующие варианты:

С фильтром

 for {
    key <- possibleKeys
    if (myMap contains key)
    int <- myMap(key)
    r <- 0 to int
  } yield (r, int)    

С getOrElse

  for {
    key <- possibleKeys
    int <- myMap.getOrElse(key, Nil)
    r <- 0 to int
  } yield (r, int)

(Оба возвращают одинаковый результат :)

List((0,1), (1,1), (0,2), (1,2), (2,2), (0,3), (1,3), (2,3), (3,3), (0,4), (1,4), (2,4), (3,4), (4,4), (0,5), (1,5), (2,5), (3,5), (4,5), (5,5), (0,6), (1,6), (2,6), (3,6), (4,6), (5,6), (6,6))

Поскольку я знаю, что Scala поддерживает параметры для понимания, я был немного удивлен, что это не сработало.

for {
    key <- possibleKeys
    int <- myMap.get(key)
    r <- 0 to int //<-- compilation error
  } yield (r, int)

Он жалуется на type mismatch; found : List[Int] required: Int

Я смутно понимаю, почему, но есть ли способ заставить эту работу работать без предложения if или методов getOrElse? (например, есть ли способ заставить работать myMap.get(key) версию?)


person Eran Medan    schedule 30.04.2013    source источник
comment
Из любопытства кажется, что ваш код не соответствует вашему описанию. Что r <- 0 to int там делает, кроме подсчета? Судя по вашему словесному описанию, вы бы хотели пропустить этот шаг и просто дать (key, int), так что мне интересно, что делает r :)   -  person Mysterious Dan    schedule 30.04.2013
comment
@MyseriousDan, просто чтобы проиллюстрировать, что я намерен использовать результат в качестве входных данных для какой-то другой итерации, словесное описание неполное, исправлю описание, спасибо   -  person Eran Medan    schedule 30.04.2013


Ответы (2)


Вы пытаетесь смешать несовместимые типы в своем для понимания. Вы можете исправить это, преобразовав опцию в Seq на примере.

for {
  key <- possibleKeys
  ints <- myMap.get(key).toSeq
  int <- ints
  r <- 0 to int
} yield (r, int)

Здесь есть довольно хорошее объяснение проблемы в этом очень похожем вопросе: Несоответствие типов в Scala Для понимания.

person Régis Jean-Gilles    schedule 30.04.2013