2010-03-23 9 views
14

Как это сделать без создания каких-либо новых коллекций? Есть что-то лучше этого?Каков правильный способ удаления элементов из измененной карты scala с использованием предиката

val m = scala.collection.mutable.Map[String, Long]("1" -> 1, "2" -> 2, "3" -> 3, "4" -> 4) 
m.foreach(t => if (t._2 % 2 == 0) m.remove(t._1)) 
println(m) 

P.S. in Scala 2.8

+4

Вопросы о коллекциях должны сообщать, требуется ли запрос 2.7 или 2.8. –

+0

Используя 2.8 в течение довольно долгого времени, уже забыл о 2.7. Спасибо, добавлено P.S. –

+2

Есть тег Scala-2.8, который вы можете добавить как указание на то, что это особый вопрос 2.8. – ams

ответ

18

retain делает, что вы хотите. В версии 2.7:

val a = collection.mutable.Map(1->"one",2->"two",3->"three") 
a: scala.collection.mutable.Map[Int,java.lang.String] = 
    Map(2 -> two, 1 -> one, 3 -> three) 

scala> a.retain((k,v) => v.length < 4) 

scala> a 
res0: scala.collection.mutable.Map[Int,java.lang.String] = 
    Map(2 -> two, 1 -> one) 

Он также работает, но я думаю, что все еще в движении, в 2.8.

+1

Похоже, что удержание устарело в 2.8: http://www.scala-lang.org/archives/downloads/distrib/files/nightly/docs/library/scala/collection/Map .html Устаревший: не может быть введен тип из-за сохранения в Iterable. –

+0

Действительно; им, возможно, придется переименовать его или придумать другой способ обхода. Я не думаю, что это просто исчезнет; это было бы глупо. Я интерпретирую эту усталость как «в потоке, может измениться». –

+0

Похоже, что устаревание будет удалено. Поэтому ответ правильный. –

0

Если вы используете immutable.Map, в 2.7 это может быть что-то вроде:

def pred(k: Int, v: String) = k % 2 == 0 

m --= (m.filter(pred(_, _)).keys 

Как нет retain доступный метод. Очевидно, что в этом случае m должен быть объявлен как var

+0

Если вы используете неизменяемую карту и, следовательно, должны создать новую, довольно легко просто фильтровать с отрицанием предиката. –

+0

Действительно, это правда: это зависит от того, что вы считаете более читаемым в данной ситуации –

2

Пер Ла Скала изменяемым карте reference page, вы можете удалить один элемент либо - = или удалить, например, так:

val m = scala.collection.mutable.Map[String, Long]("1" -> 1, "2" -> 2, "3" -> 3, "4" -> 4) 
m -= "1" // returns m 
m.remove("2") // returns Some(2) 

Разница заключается в том, что - = возвращает исходный объект карты, а remove возвращает параметр, содержащий значение, соответствующее удаляемому ключу (если таковой был.)

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