Ciri Scala MapLike
memiliki metode
mapValues [C] (f: (B) ⇒ C): Map[A, C]
Tapi terkadang saya menginginkan tipe yang berbeda:
mapKeysAndValues [C] (f: (A, B) ⇒ C): Map[A, C]
Apakah ada cara sederhana untuk melakukan ini yang saya lewatkan? Tentu saja, ini bisa dilakukan dengan lipatan.
f : (A,B) => (A,C)
, maka Anda bisam.map(f.tupled)
. Bekerja denganval f = (x: String, y: Int) => (x, y+1)
tetapi anehnya repl mengeluh jika saya mendefinisikanf
dengan ekuivalendef
.case
dicapai kata kunci di sini?{case (key, value) => ...}
hanyalah pencocokan pola dalam kasus ini. Alih-alih memberikan fungsi ke amap
, saya memberikannya fungsi parsial.case
akan membiarkan Anda memasukkan tipe ke dalam polanya, tetapi ini tidak aman karena dapat membuat kesalahan waktu proses (karena ini hanya kecocokan pola). Sementara itu, jika Anda pernah mengubah struktur koleksi di bawahmap
fungsi sehingga ada terlalu sedikit atau terlalu banyak objek untuk diinterpretasikan(key, value)
, maka sekali lagi, saya berharap Anda akan mendapatkan error runtime. :(Bagaimana dengan kode ini:
val m = Map(1 -> "one", 2 -> "two") def f(k: Int, v: String) = k + "-" + v m map {case (k, v) => (k, f(k, v))}
Yang menghasilkan:
Map(1 -> 1-one, 2 -> 2-two)
Ini dapat dikemas ke dalam metode utilitas:
def mapKeysAndValues[A,B,C](input: Map[A,B], fun: (A, B) => C) = input map {case(k,v) => (k, fun(k, v))}
Pemakaian:
mapKeysAndValues( Map(1 -> "one", 2 -> "two"), (k: Int, v: String) => k + "-" + v )
sumber
MapLike#transform
?m map (t => (t._1, t._2 + 1)) m map (t => t._1 -> t._2 + 1)
sumber
Dengan beberapa Scalaz:
scala> def fst[A, B] = (x: (A, B)) => x._1 fst: [A, B]=> (A, B) => A scala> Map(1 -> "Lorem", 2 -> "Ipsum").map(fst &&& Function.tupled(_.toString + _)) res1: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> 1Lorem, 2 -> 2Ipsum)
Saya lebih suka solusi @ tenshi.
sumber
Anda dapat membuat kelas utilitas:
class MyMapLike[K,V](m:MapLike[K,V,_]){ def mapKeysAndValues[R](f: (K, V) => R)={ m.map{case (k,v)=> f(k,v)} } } object MyMapLike{ implicit def maplike2mymaplike[K,V](ml:MapLike[K,V,_]):MyMapLike[K,V]=new MyMapLike(m) } import MyMapLike._ Map(1 -> "one", 2 -> "two").mapKeysAndValues(k,v=>v*k)
Kode tidak diuji tetapi harus bekerja sama seperti itu.
sumber