টিপলের তালিকায় মানচিত্রে রূপান্তর করুন (এবং ডুপ্লিকেট কী দিয়েছিলেন?)


92

আমি সদৃশ কী দ্বারা টুপলের একটি তালিকা [("a","b"),("c","d"),("a","f")]মানচিত্রে রূপান্তর করার একটি দুর্দান্ত উপায় সম্পর্কে ভাবছিলাম ("a" -> ["b", "f"], "c" -> ["d"])। সাধারণত (অজগরটিতে), আমি তালিকার উপরে একটি খালি মানচিত্র এবং ফর্ম লুপ তৈরি করে নকল কীটি পরীক্ষা করবো। তবে আমি এখানে আরও কিছু স্কেল-ইশ এবং চতুর সমাধানের সন্ধান করছি।

বিটিডব্লিউ, এখানে আমি যে ধরণের কী-মান ব্যবহার (Int, Node)করি তা হ'ল এবং আমি একটি মানচিত্রে রূপান্তর করতে চাই(Int -> NodeSeq)

উত্তর:


79

গ্রুপ এবং তারপরে প্রকল্প:

scala> val x = List("a" -> "b", "c" -> "d", "a" -> "f")
//x: List[(java.lang.String, java.lang.String)] = List((a,b), (c,d), (a,f))
scala> x.groupBy(_._1).map { case (k,v) => (k,v.map(_._2))}
//res1: scala.collection.immutable.Map[java.lang.String,List[java.lang.String]] = Map(c -> List(d), a -> List(b, f))

ভাঁজগুলি ব্যবহার করার মতো আরও স্কালিশ উপায়, সেখানকার মতো ( map fপদক্ষেপ এড়ান )।


125

এমন গুগলারের জন্য যা সদৃশদের প্রত্যাশা করে না বা ডিফল্ট সদৃশ হ্যান্ডলিং নীতিমালা দিয়ে ভাল রয়েছে :

List("a" -> 1, "b" -> 2).toMap
// Result: Map(a -> 1, c -> 2)

২.১২ হিসাবে, ডিফল্ট নীতিটি পড়ে:

সদৃশ কীগুলি পরবর্তী কীগুলির দ্বারা ওভাররাইট করা হবে: যদি এটি একটি আনর্ডারড সংগ্রহ হয় তবে ফলস্বরূপ মানচিত্রে কোন কীটি অপরিজ্ঞাত।


58

এখানে আরও একটি বিকল্প রয়েছে:

x.groupBy(_._1).mapValues(_.map(_._2))

এটি আমাদের একটি দেয় Map[String, SeqView[String,Seq[_]]]... এটি উদ্দেশ্যমূলক?
— Luigi Plinge

4
@ লুইজিপ্লিনজ SeqView[String,Seq[_]]এও একটি Seq[String]। এখনও অনড় দৃষ্টিতে আমি তা সার্থক মনে করি না, তাই আমি এটি সরিয়েছি view। mapValuesমানগুলিতে যাই হোক না কেন একটি ভিউ করবে।
— ড্যানিয়েল সি সোব্রাল

এটি আমার ক্ষেত্রে (কোর্স হোমওয়ার্ক) পুরোপুরিভাবে কাজটি করেছে: অলস ভ্যাল ডিকোরিয়ালটি বাইকসিওরেন্সস: মানচিত্র [ঘটনা, তালিকা [শব্দ]] = pairs ভাল জোড় = জন্য (কার্ফোর্ড <- অভিধান) ফলন cur ভল curWordOccurrences = শব্দঅ্যাক্সিয়েন্সস (curWord), কার্ফোর্ড)} જોડીઓ.groupBy ( ._1)। ম্যাপভ্যালু (। ম্যাপ (_._ 2))}
— জেসনজি

মানচিত্রভ্যালুগুলি কোনও মানচিত্রের একটি দৃশ্য ফিরিয়ে দেয়, নতুন মানচিত্র নয়- স্কালা
— ইন্ডেক্স। html#

4
সম্ভবত চান x.groupBy(_._1).mapValues(_.map(_._2)).map(identity)কারণ mapValuesপ্রতিবার এটি ব্যবহার করার সময় এক্সপ্রেশনটি পুনরায় সংশ্লেষ করা হবে। দেখুন issues.scala-lang.org/browse/SI-7005
— জেফ্রি Aguilera

20

নকলগুলি সম্পর্কে যত্নশীল এমন গুগলারের জন্য:

implicit class Pairs[A, B](p: List[(A, B)]) {
  def toMultiMap: Map[A, List[B]] = p.groupBy(_._1).mapValues(_.map(_._2))
}

> List("a" -> "b", "a" -> "c", "d" -> "e").toMultiMap
> Map("a" -> List("b", "c"), "d" -> List("e")) 

12

শুরু করে Scala 2.13, বেশিরভাগ সংগ্রহগুলিতে গ্রুপম্যাপ পদ্ধতি সরবরাহ করা হয় যা এর নাম অনুসারে) এর সমতুল্য (আরও দক্ষ) groupByঅনুসরণ করা হয় mapValues:

List("a" -> "b", "c" -> "d", "a" -> "f").groupMap(_._1)(_._2)
// Map[String,List[String]] = Map(a -> List(b, f), c -> List(d))

এই:

  • groupটিপলসের প্রথম অংশের উপর ভিত্তি করে উপাদানসমূহ ( গ্রুপ মানচিত্রের গোষ্ঠী অংশ )

  • mapএর দ্বিতীয় দ্বিখণ্ডিত অংশ (গ্রুপ মানচিত্রের মানচিত্রের অংশ ) গ্রহণ করে গোষ্ঠীভুক্ত মানগুলি

এটি একটি সমতুল্য list.groupBy(_._1).mapValues(_.map(_._2))তবে তালিকার এক পাসে সঞ্চালিত ।


4

ডুপ্লিকেট কীগুলি পরিচালনা করে মানচিত্রের তালিকায় টিপলগুলির একটি তালিকা রূপান্তর করার জন্য এখানে আরও স্কাল আইডিয়োমেটিক উপায়। আপনি একটি ভাঁজ ব্যবহার করতে চান।

val x = List("a" -> "b", "c" -> "d", "a" -> "f")

x.foldLeft(Map.empty[String, Seq[String]]) { case (acc, (k, v)) =>
  acc.updated(k, acc.getOrElse(k, Seq.empty[String]) ++ Seq(v))
}

res0: scala.collection.immutable.Map[String,Seq[String]] = Map(a -> List(b, f), c -> List(d))

4
আপনি কেন মনে করেন এটি এখানে দেওয়া গ্রুপ-ম্যাপভ্যালু সলিউশনগুলির চেয়ে স্ক্যাল-স্টাইল বেশি?
— Make42

@ ওম-নোম-নোম স্টেটমেন্ট "আরও ভালোভাবে ভাঁজ ব্যবহার করার উপায়, সেখানে (ম্যাপ এফ স্টেপ এড়িয়ে যাওয়া)" "
— cevaris

আমি একটি যৌক্তিক যুক্তির জন্য আশা করি ;-)। ওম-নাম-মনোনীত বা লিঙ্কযুক্ত নিবন্ধটিই আমার প্রশ্নের প্রমাণ সরবরাহ করে না। (বা আমি এটি মিস করেছি?)
— Make 42

4
@ মেক 42২ এটির মোকাবেলার আরও একটি সহজ উপায়, যেহেতু সমস্ত মনাদ মনোহাইড এবং আইন অনুসারে মনোয়েডগুলি ভাজযোগ্য। এফপি-তে, বস্তু এবং ইভেন্টগুলি মোনাড হিসাবে মডেল করা হয়, এবং সমস্ত মনাদ গোষ্ঠী দ্বারা প্রয়োগ করা হয় না।
— soote

4

নীচে আপনি কয়েকটি সমাধান সন্ধান করতে পারেন। (গ্রুপ বাই, ফোল্ড লেফট, সমষ্টি, স্পার্ক)

val list: List[(String, String)] = List(("a","b"),("c","d"),("a","f"))

গ্রুপ-বাই প্রকরণ

list.groupBy(_._1).map(v => (v._1, v._2.map(_._2)))

বাম প্রকরণ ভাঁজ করুন

list.foldLeft[Map[String, List[String]]](Map())((acc, value) => {
  acc.get(value._1).fold(acc ++ Map(value._1 -> List(value._2))){ v =>
    acc ++ Map(value._1 -> (value._2 :: v))
  }
})

সমষ্টিগত পার্থক্য - বাম ভাঁজ করার অনুরূপ

list.aggregate[Map[String, List[String]]](Map())(
  (acc, value) => acc.get(value._1).fold(acc ++ Map(value._1 -> 
    List(value._2))){ v =>
     acc ++ Map(value._1 -> (value._2 :: v))
  },
  (l, r) => l ++ r
)

স্পার্কের তারতম্য - বড় ডেটা সেটগুলির জন্য (আরডিডি থেকে আরডিডি থেকে একটি সরল মানচিত্রে রূপান্তর)

import org.apache.spark.rdd._
import org.apache.spark.{SparkContext, SparkConf}

val conf: SparkConf = new 
SparkConf().setAppName("Spark").setMaster("local")
val sc: SparkContext = new SparkContext (conf)

// This gives you a rdd of the same result
val rdd: RDD[(String, List[String])] = sc.parallelize(list).combineByKey(
   (value: String) => List(value),
   (acc: List[String], value) => value :: acc,
   (accLeft: List[String], accRight: List[String]) => accLeft ::: accRight
)

// To convert this RDD back to a Map[(String, List[String])] you can do the following
rdd.collect().toMap

2

আপনি এটি চেষ্টা করতে পারেন

scala> val b = new Array[Int](3)
// b: Array[Int] = Array(0, 0, 0)
scala> val c = b.map(x => (x -> x * 2))
// c: Array[(Int, Int)] = Array((1,2), (2,4), (3,6))
scala> val d = Map(c : _*)
// d: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 2 -> 4, 3 -> 6)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.