Какъв е правилният начин за премахване на елементи от променлива карта на 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. в Scala 2.8


person Oleg Galako    schedule 23.03.2010    source източник
comment
Въпросите относно колекциите трябва да показват дали се търси отговор 2,7 или 2,8.   -  person Randall Schulz    schedule 23.03.2010
comment
Използвах 2.8 от доста дълго време, но вече забравих за 2.7. Благодаря, добави P.S.   -  person Oleg Galako    schedule 24.03.2010
comment
Има таг Scala-2.8, който можете да добавите като индикация, че това е специфичен въпрос за 2.8.   -  person ams    schedule 24.03.2010
comment
Благодаря, заместих предиката с него   -  person Oleg Galako    schedule 25.03.2010


Отговори (3)


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.

person Rex Kerr    schedule 23.03.2010
comment
Изглежда, че запазването е отхвърлено във 2.8: scala-lang.org/archives/downloads/distrib/files/nightly/docs/ отхвърлено: типът не може да бъде изведен поради запазване в Iterable. - person Oleg Galako; 23.03.2010
comment
Наистина; може да се наложи да го преименуват или да измислят друго решение. Не мисля, че просто ще изчезне; това би било малко глупаво. Тълкувам това отхвърляне като течение, може да се промени. - person Rex Kerr; 23.03.2010
comment
Изглежда, че оттеглянето ще бъде премахнато. Така че отговорът е правилен. - person Oleg Galako; 28.03.2010

Според променливата карта на Scala референтната страница, вие може да премахне един елемент с -= или премахне, така:

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 връща опция, съдържаща стойността, съответстваща на премахнатия ключ (ако е имало такъв).

Разбира се, както показват други отговори, ако искате да премахнете много елементи въз основа на условие, трябва да разгледате запазването, филтрирането и т.н.

person Jonathan Stray    schedule 18.10.2012

Ако използвате immutable.Map, в 2.7 може да е нещо като:

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

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

Тъй като няма наличен метод retain. Очевидно в този случай m трябва да се декларира като var

person oxbow_lakes    schedule 23.03.2010
comment
Ако използвате неизменна карта и следователно трябва да създадете нова, е доста лесно просто да филтрирате с отрицанието на предиката. - person Randall Schulz; 23.03.2010
comment
Всъщност това е вярно: зависи какво смятате за по-разбираемо в дадена ситуация - person oxbow_lakes; 23.03.2010