แผนภูมิเทียบเท่า IEnumerable LINQ ใน Scala? [ทำซ้ำ]

อาจซ้ำกัน:
อะนาล็อก LINQ ใน Scala

ฉันกำลังมองหาแผนภูมิที่แสดงค่าเทียบเท่าในวิธี Scala ของ LINQ สำหรับ IEnumerable:

  • อันดับแรกคือหัว
  • เลือกคือแผนที่
  • SingleOrDefault คือ ... (ฉันไม่รู้)
  • ... และอื่น ๆ

ไม่มีใครรู้อะไรเกี่ยวกับตาราง "แปล" ดังกล่าวหรือไม่


person greenoldman    schedule 12.11.2011    source แหล่งที่มา


คำตอบ (2)


ฉันแค่แสดงรายการฟังก์ชันที่เทียบเท่าจาก Enumerable<A> เท่านั้น ขณะนี้ยังไม่สมบูรณ์ ฉันจะพยายามอัปเดตสิ่งนี้ในภายหลังด้วยเพิ่มเติม

xs.Aggregate(accumFunc)              -> xs.reduceLeft(accumFunc)
xs.Aggregate(seed, accumFunc)        -> xs.foldLeft(seed)(accumFunc)
xs.Aggregate(seed, accumFunc, trans) -> trans(xs.foldLeft(seed)(accumFunc))
xs.All(pred)                         -> xs.forall(pred)
xs.Any()                             -> xs.nonEmpty
xs.Any(pred)                         -> xs.exists(pred)
xs.AsEnumerable()                    -> xs.asTraversable // roughly
xs.Average()                         -> xs.sum / xs.length
xs.Average(trans)                    -> trans(xs.sum / xs.length)
xs.Cast<A>()                         -> xs.map(_.asInstanceOf[A])
xs.Concat(ys)                        -> xs ++ ys
xs.Contains(x)                       -> xs.contains(x) //////
xs.Contains(x, eq)                   -> xs.exists(eq(x, _))
xs.Count()                           -> xs.size
xs.Count(pred)                       -> xs.count(pred)
xs.DefaultIfEmpty()                  -> if(xs.isEmpty) List(0) else xs // Use `mzero` (from Scalaz) instead of 0 for more genericity
xs.DefaultIfEmpty(v)                 -> if(xs.isEmpty) List(v) else xs
xs.Distinct()                        -> xs.distinct
xs.ElementAt(i)                      -> xs(i)
xs.ElementAtOrDefault(i)             -> xs.lift(i).orZero // `orZero` is from Scalaz
xs.Except(ys)                        -> xs.diff(ys)
xs.First()                           -> xs.head
xs.First(pred)                       -> xs.find(pred) // returns an `Option`
xs.FirstOrDefault()                  -> xs.headOption.orZero
xs.FirstOrDefault(pred)              -> xs.find(pred).orZero
xs.GroupBy(f)                        -> xs.groupBy(f)
xs.GroupBy(f, g)                     -> xs.groupBy(f).mapValues(_.map(g))
xs.Intersect(ys)                     -> xs.intersect(ys)
xs.Last()                            -> xs.last
xs.Last(pred)                        -> xs.reverseIterator.find(pred) // returns an `Option`
xs.LastOrDefault()                   -> xs.lastOption.orZero
xs.LastOrDefault(pred)               -> xs.reverseIterator.find(pred).orZero
xs.Max()                             -> xs.max
xs.Max(f)                            -> xs.maxBy(f)
xs.Min()                             -> xs.min
xs.Min(f)                            -> xs.minBy(f)
xs.OfType<A>()                       -> xs.collect { case x: A => x }
xs.OrderBy(f)                        -> xs.sortBy(f)
xs.OrderBy(f, comp)                  -> xs.sortBy(f)(comp) // `comp` is an `Ordering`.
xs.OrderByDescending(f)              -> xs.sortBy(f)(implicitly[Ordering[A]].reverse)
xs.OrderByDescending(f, comp)        -> xs.sortBy(f)(comp.reverse)
Enumerable.Range(start, count)       -> start until start + count
Enumerable.Repeat(x, times)          -> Iterator.continually(x).take(times)
xs.Reverse()                         -> xs.reverse
xs.Select(trans)                     -> xs.map(trans) // For indexed overload, first `zipWithIndex` and then `map`.
xs.SelectMany(trans)                 -> xs.flatMap(trans)
xs.SequenceEqual(ys)                 -> xs.sameElements(ys)
xs.Skip(n)                           -> xs.drop(n)
xs.SkipWhile(pred)                   -> xs.dropWhile(pred)
xs.Sum()                             -> xs.sum
xs.Sum(f)                            -> xs.map(f).sum // or `xs.foldMap(f)`. Requires Scalaz.
xs.Take(n)                           -> xs.take(n)
xs.TakeWhile(pred)                   -> xs.takeWhile(pred)
xs.OrderBy(f).ThenBy(g)              -> xs.sortBy(x => (f(x), g(x))) // Or: xs.sortBy(f &&& g). `&&&` is from Scalaz.
xs.ToArray()                         -> xs.toArray // Use `xs.toIndexedSeq` for immutable indexed sequence.
xs.ToDictionary(f)                   -> xs.map(f.first).toMap // `first` is from Scalaz. When f = identity, you can just write `xs.toMap`.
xs.ToList()                          -> xs.toList // This returns an immutable list. Use `xs.toBuffer` if you want a mutable list.
xs.Union(ys)                         -> xs.union(ys)
xs.Where(pred)                       -> xs.filter(pred)
xs.Zip(ys, f)                        -> (xs, ys).zipped.map(f) // When f = identity, use `xs.zip(ys)`

ไม่มีฟังก์ชันใดที่เทียบเท่าโดยตรงกับบางฟังก์ชัน แต่คุณสามารถหมุนฟังก์ชันของคุณเองได้อย่างง่ายดาย นี่คือฟังก์ชันบางอย่างดังกล่าว

โสด:

def single[A](xs: Traversable[A]): A = {
  if(xs.isEmpty) sys error "Empty sequence!"
  else if(xs.size > 1) sys error "More than one elements!"
  else xs.head
}

SingleOrDefault:

def singleOrDefault[A : Zero](xs: Traversable[A]): A = {
  if(xs.isEmpty) mzero
  else if(xs.size > 1) sys error "More than one elements!"
  else xs.head
}

เข้าร่วม:

def join[A, B, K, R](outer: Traversable[A], inner: Traversable[B])
    (outKey: A => K, inKey: B => K, f: (A, B) => R): Traversable[R] = {
  for(o <- outer; i <- inner; if outKey(o) == inKey(i)) yield f(o, i)
}

เข้าร่วมกลุ่ม:

def groupJoin[A, B, K, R](outer: Traversable[A], inner: Traversable[B])
    (outKey: A => K, inKey: B => K, f: (A, Traversable[B]) => R): Traversable[R] = {
  for(o <- outer) yield {
    val zs = for(i <- inner; if outKey(o) == inKey(i)) yield i
    f(o, zs)
  }
}

หมายเหตุ:

  1. ในสำนวนสกาลา โดยทั่วไปนิยมใช้ฟังก์ชันทั้งหมดมากกว่าฟังก์ชันบางส่วน ดังนั้น การใช้สำนวน single และ singleOrDefault จะสร้างค่าประเภท Either[Exception, A] แทนที่จะเป็น A ตัวอย่างเช่น นี่คือการใช้งาน single ที่ได้รับการปรับปรุงซึ่งส่งคืน Either[Exception, A]

    def single[A](xs: Traversable[A]): Either[Exception, A] = {
      if(xs.isEmpty) Left(new RuntimeException("Empty sequence!"))
      else if(xs.size > 1) Left(new RuntimeException("More than one elements!"))
      else Right(xs.head)
    }
    
  2. Zero/mzero ของ Scalaz นั้นไม่เหมือนกับกลไกค่า default ของ C# สำหรับรายละเอียด โปรดดูที่สิ่งนี้ โพสต์ที่ฉันเขียนในหัวข้อนี้เมื่อนานมาแล้ว

  3. คุณสามารถใช้รูปแบบ rich-my-library เพื่อให้ได้ผลเช่นเดียวกับวิธีการขยายของ C# โปรดดูสิ่งนี้ และ สิ่งนี้เพื่อดูรายละเอียด

person Community    schedule 12.11.2011
comment
ขอบคุณมาก!!! เมื่อทำการอัพเดต หากไม่มี mapping 1:1 กรุณาระบุเป็น no mapping 1:1 ขอบคุณล่วงหน้า - person greenoldman; 13.11.2011
comment
Aggregate อันที่สามไม่ถูกต้อง trans(xs.foldLeft(seed)(accumFunc)) เหมาะสม - person Daniel C. Sobral; 13.11.2011
comment
@missingfaktor: เป็นไปได้ไหมที่จะใช้รายการนั้นกับ docs.scala-lang.org - person soc; 13.11.2011
comment
@ DanielC.Sobral: ขอบคุณสำหรับการแก้ไข! - person missingfaktor; 13.11.2011
comment
@soc: นั่นเป็นความคิดที่ดี มีฟังก์ชันบางอย่าง (Single*, GroupJoin, Join ฯลฯ) ที่ยังต้องครอบคลุมอยู่ เมื่อเสร็จแล้ว คุณสามารถใช้สิ่งนี้กับ docs.scala-lang.org ได้ - person missingfaktor; 13.11.2011
comment
@soc: ดูดีขึ้นมากด้วย until อัปเดตแล้ว ขอบคุณ! - person missingfaktor; 13.11.2011
comment
@macias: คุณหมายถึงอะไร? แทบจะไม่มีสิ่งใดเทียบเท่า 1:1 เลย - person missingfaktor; 13.11.2011
comment
@missingfaktor ฉันคิดว่าการแปลซึ่งต้องการบางสิ่งที่สำคัญมากกว่า 1-liner ไม่ใช่การทำแผนที่ 1: 1 - person greenoldman; 13.11.2011
comment
@soc: ฉันอัปเดตคำตอบของฉัน ตอนนี้คุณสามารถใช้กับ docs.scala-lang.org ได้แล้ว :-) - person missingfaktor; 13.11.2011
comment
@macias: ตรวจสอบคำตอบที่อัปเดต ฟังก์ชันที่ไม่มีการแมป 1:1 (ตามคำจำกัดความของคุณ) ได้รับการอธิบายแยกกัน - person missingfaktor; 13.11.2011
comment
@missingfaktor ฉันจะโหวตให้คุณ +100 ได้อย่างไร ;-) ตอนนี้ฉันยังใหม่กับ Scala แต่ฉันคิดว่าการตรวจสอบขนาดครั้งที่สองใน SingleXX จะเร็วกว่าด้วย coll.tail.isEmpty - นี่ควรเป็น O(1) แทนที่จะเป็น O(n) ของขนาด - person greenoldman; 14.11.2011
comment
@macias: โอ้จริง ๆ ส่วนใหญ่ฉันใช้ Vector แทน List จึงมีการกำกับดูแล. ฉันจะอัปเดตรหัสตามข้อเสนอแนะของคุณ - person missingfaktor; 14.11.2011
comment
@macias: ฉันเขียนโค้ดเหล่านี้โดยคำนึงถึงอินเทอร์เฟซการรวบรวมทั่วไป (เช่น Traversable, Seq) ข้อเท็จจริงที่ว่า size คือการดำเนินการ O(n) นั้นเฉพาะเจาะจงกับรายการ และไม่จำเป็นต้องนำไปใช้กับคอลเลกชันประเภทอื่น ตอนนี้ฉันกำลังอัปเดตโค้ดตามนั้น - person missingfaktor; 14.11.2011
comment
สิ่งนี้มีประโยชน์อย่างเหลือเชื่อ พวกเขาจะต้องสร้างมาตรฐาน ISO สำหรับ API คอลเลกชัน - person Dmitry Ornatsky; 08.02.2012
comment
@DmitryOrnatsky ขอบคุณ :) เราไม่จำเป็นต้องไปไกลถึงขนาดนั้น มันจะเกินพอแล้วหาก API ของ Microsoft สอดคล้องกับชื่อและแบบแผนทั่วไป แทนที่จะคิดค้นสิ่งใหม่ - person missingfaktor; 08.02.2012
comment
แผนภูมิของคุณไม่ถูกต้องสำหรับ Average: xs.Average(trans) ผิด ควรเป็น trans(xs).sum / xs.length สำหรับประเภทที่ไม่สามารถเป็นค่าว่างได้ สำหรับ xs.Average(): ค่าเฉลี่ยของ ints คือสองเท่า ไม่ใช่ int เช่นกัน ในทั้งสองกรณีสำหรับประเภท nullable จะไม่นับค่า null - person Vlad; 21.10.2013
comment
เช่นกัน xs.Max(f) ของ LINQ ก็คือ f(xs).max จริงๆ - person Vlad; 21.10.2013
comment
ยอดเยี่ยม! ฉันจะลงคะแนนให้คำตอบนี้วันละครั้ง! - person python_kaa; 15.01.2015
comment
แล้ว partition ล่ะ: def partition(p: (A) ⇒ Boolean): (List[A], List[A]) แบ่งพาร์ติชั่นคอลเลกชั่นแบบข้ามผ่านได้นี้เป็นสองคอลเลกชั่นแบบเปลี่ยนผ่านได้ตามเพรดิเคต - person yǝsʞǝla; 06.02.2015

ฉันไม่รู้อะไรเกี่ยวกับ C# หรือ LINQ แต่นี่คือสิ่งที่คุณกำลังมองหาใช่ไหม

scala> val l = List(1, 2, 3, 4, 5)
l: List[Int] = List(1, 2, 3, 4, 5)

scala> l.head
res0: Int = 1

scala> l.headOption
res1: Option[Int] = Some(1)

scala> l.map(_.toString)
res2: List[java.lang.String] = List(1, 2, 3, 4, 5)

scala> l(1)
res3: Int = 2

ไม่มีวิธีการรับองค์ประกอบหรือค่าเริ่มต้น แต่จะได้ผล:

scala> scala.util.control.Exception.allCatch.opt(l(5)) getOrElse 0
res4: Int = 0
person pr1001    schedule 12.11.2011
comment
ขอบคุณ แต่ฉันกำลังมองหาการแปล LINQ -› Scala ที่สมบูรณ์ เพื่อให้จิตใจฉันดำเนินไปถูกทางเร็วขึ้น บางสิ่งบางอย่างที่จะพิมพ์อ่านและจดจำ - person greenoldman; 12.11.2011
comment
สำหรับอันสุดท้าย คุณก็ทำได้ l.lift(5).getOrElse(0) - person missingfaktor; 12.11.2011