แมปทั้งคีย์และค่าของแผนที่สกาล่า


89

MapLikeลักษณะของสกาล่ามีวิธีการ

mapValues [C] (f: (B) ⇒ C): Map[A, C] 

แต่บางครั้งฉันก็ต้องการประเภทอื่น:

mapKeysAndValues [C] (f: (A, B) ⇒ C): Map[A, C] 

มีวิธีง่ายๆในการทำสิ่งนี้ที่ฉันขาดหายไปหรือไม่? แน่นอนว่าสามารถทำได้ด้วยการพับ

คำตอบ:


167

mapวิธีการวนซ้ำแม้ว่าทุก(key, value)คู่ คุณสามารถใช้งานได้ดังนี้:

val m = Map("a" -> 1, "b" -> 2)

val incM = m map {case (key, value) => (key, value + 1)}

8
หากคุณมีฟังก์ชั่นแล้วคุณสามารถเพียงf : (A,B) => (A,C) m.map(f.tupled)ใช้งานได้กับval f = (x: String, y: Int) => (x, y+1)การจำลอง แต่แปลกถ้าฉันกำหนดfเทียบเท่ากับdef.
Dan Burton

2
คำหลักcaseบรรลุอะไรที่นี่
ทุกหนทุกแห่ง

@Omnipresent {case (key, value) => ...}เป็นเพียงการจับคู่รูปแบบในกรณีนี้ แทนที่จะให้ฟังก์ชันกับ a mapฉันให้ฟังก์ชันบางส่วน
tenshi

หมายเหตุ: caseจะช่วยให้คุณสามารถใส่ประเภทในรูปแบบได้ แต่ไม่ปลอดภัยเนื่องจากอาจสร้างข้อผิดพลาดรันไทม์ (เนื่องจากเป็นเพียงรูปแบบที่ตรงกัน) ในขณะเดียวกันหากคุณเคยเปลี่ยนโครงสร้างของคอลเลกชันที่อยู่ใต้mapฟังก์ชันเพื่อให้มีวัตถุน้อยเกินไปหรือมากเกินไปที่จะตีความเป็น(key, value)ฉันคาดว่าคุณจะได้รับข้อผิดพลาดรันไทม์ :(
combinatorist

8

รหัสนี้คืออะไร:

val m = Map(1 -> "one", 2 -> "two")
def f(k: Int, v: String) = k + "-" + v
m map {case (k, v) => (k, f(k, v))}

ซึ่งผลิต:

 Map(1 -> 1-one, 2 -> 2-two)

สิ่งนี้สามารถบรรจุลงในวิธียูทิลิตี้:

def mapKeysAndValues[A,B,C](input: Map[A,B], fun: (A, B) => C) = 
  input map {case(k,v) => (k, fun(k, v))}

การใช้งาน:

mapKeysAndValues(
  Map(1 -> "one", 2 -> "two"), 
  (k: Int, v: String) => k + "-" + v
)

นี่ไม่เหมือนกับMapLike#transform?
Hosam Aly


2

ด้วย 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)

ชอบวิธีแก้ของ @ tenshi ดีกว่า


0

คุณสามารถสร้างคลาสยูทิลิตี้:

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)

ไม่ได้ทดสอบรหัส แต่ควรใช้งานได้เหมือนกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.