2016-10-04 2 views
1

У меня есть простая картаИспользование filterNot с карты

val m = Map("a1" -> "1", "b2" -> "2", "c3" -> "3") 
val someList = List("b", "d") 
m.filterNot((k,v) => someList.exist(l => k.startsWith(l))) 

Я получаю сообщение об ошибке:

error: missing parameter type 

я делаю что-то глупое здесь я уверен, почему ISN»это компиляции?

ответ

3

filterNot нуждается в ключевом слове case и {} при извлечении k, v из кортежа.

отмечают, что его не exist его exists

m.filterNot { case (k,v) => someList.exists(l => k.startsWith(l)) } 

или

m.filterNot(pair => someList.exists(l => pair._1.startsWith(l))) 

Объяснение

Как вы извлекаете K, V из кортежа, используя синтаксис экстрактор у вас есть использовать ключевое слово case и {}

Без синтаксиса экстрактор вы можете сделать

m.filterNot(pair => someList.exists(l => pair._1.startsWith(l))) 

Scala REPL

scala> val m = Map("a1" -> "1", "b2" -> "2", "c3" -> "3") 
m: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, b2 -> 2, c3 -> 3) 

scala> val someList = List("b", "d") 
someList: List[String] = List(b, d) 

scala> m.filterNot { case (k,v) => someList.exists(l => k.startsWith(l)) } 
res15: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, c3 -> 3) 

Без синтаксиса экстрактор

Теперь вам не нужно использовать case ключевое слово и {} как ш е не используют извлечения ключа и значения с помощью экстрактора синтаксиса

scala> m.filterNot(pair => someList.exists(l => pair._1.startsWith(l))) 
res18: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, c3 -> 3) 

scala> val m = Map("a1" -> "1", "b2" -> "2", "c3" -> "3") 
m: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, b2 -> 2, c3 -> 3) 

scala> val someList = List("b", "d") 
someList: List[String] = List(b, d) 

scala> m.filterNot(pair => someList.exists(l => pair._1.startsWith(l))) 
res19: scala.collection.immutable.Map[String,String] = Map(a1 -> 1, c3 -> 3) 
+1

Или просто: '(пара => someList.exists (pair._1.startsWith))' – jwvh

+0

@jwvh я уже упомянул об этом в ответе – pamu

+0

Хмм, я этого не вижу. Все ваши примеры явно передают параметр 'l':' startsWith (l) 'На самом деле его можно уменьшить еще больше,' m.filterNot (someList существует _._ 1.startsWith) ', но теперь нам грозит затенение код, будучи слишком симпатичным с синтаксисом. – jwvh

2

Вопрос заключается в следующем: метод filterNot принимает один параметр, в то время как вы определяете список из двух параметров. Это смущает компилятор, и это сообщение является результатом.

Для того, чтобы решить эту проблему, вы можете использовать следующий синтаксис (обратите внимание на использование сопоставления образца с case ключевым словом):

m.filterNot { case (k,v) => someList.exist(l => k.startsWith(l)) } 

Использованием по шаблону, как это создает PartialFunction, который будет разлагаться ключом и значение и применяться как нормальная функция для вашего Map.

+1

Обратите внимание, что поскольку вы не используете значение, вы можете отбросить значение с помощью '_' следующим образом:' m.filterNot {case (k, _) => someList.exist (l => k.startsWith (l)) } ' – stefanobaghino

+0

В какой-то момент в будущем эта досада будет удалена в соответствии с создателем языка Мартином Одерским: https://youtu.be/_2oGY8l67jk?t=34m50s – stefanobaghino

0

Используя для синтаксиса понимания, экстракции и фильтрации может быть достигнуто следующим образом,

for ([email protected](k,v) <- m; l <- someList if !k.startsWith(l)) yield pair 
Смежные вопросы