Bagan setara LINQ IEnumerable di Scala? [duplikat]

Kemungkinan Duplikat:
Analog LINQ di Scala

Saya mencari bagan yang menunjukkan persamaan dalam metode Scala dari LINQ untuk IEnumerable:

  • Yang pertama adalah kepala
  • Pilih adalah peta
  • SingleOrDefault adalah ... (Saya tidak tahu)
  • ... dan seterusnya

Adakah yang tahu tentang tabel "terjemahan" seperti itu?


person greenoldman    schedule 12.11.2011    source sumber


Jawaban (2)


Saya hanya mencantumkan fungsi yang setara dari Enumerable<A>. Ini belum lengkap sampai sekarang. Saya akan mencoba memperbaruinya nanti dengan lebih banyak lagi.

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)`

Tidak ada persamaan langsung untuk beberapa fungsi, tetapi cukup mudah untuk menjalankannya sendiri. Berikut beberapa fungsinya.

Lajang:

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
}

Bergabung:

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)
}

Gabung Grup:

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)
  }
}

Catatan:

  1. Dalam Scala idiomatik, fungsi total umumnya lebih disukai daripada fungsi parsial. Jadi, implementasi idiomatis dari single dan singleOrDefault akan menghasilkan nilai bertipe Either[Exception, A], bukan A. Misalnya, berikut adalah implementasi halus dari single yang mengembalikan 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 tidak sama dengan mekanisme nilai default C#. Untuk detailnya, Anda dapat merujuk ke ini postingan yang saya tulis tentang topik ini beberapa waktu lalu.

  3. Anda dapat menggunakan pola memperkaya perpustakaan saya untuk mencapai efek yang sama seperti metode ekstensi C#. Lihat ini dan ini untuk detailnya.

person Community    schedule 12.11.2011
comment
Terima kasih banyak!!! Saat update, jika tidak ada pemetaan 1:1, harap dicantumkan saja sebagai pemetaan tidak ada 1:1, terima kasih sebelumnya. - person greenoldman; 13.11.2011
comment
Aggregate ketiga salah. trans(xs.foldLeft(seed)(accumFunc)) tepat. - person Daniel C. Sobral; 13.11.2011
comment
@missingfaktor: Apakah daftar itu dapat digunakan untuk docs.scala-lang.org? - person soc; 13.11.2011
comment
@DanielC.Sobral: Terima kasih atas koreksinya! - person missingfaktor; 13.11.2011
comment
@soc: Itu ide bagus. Ada beberapa fungsi (Single*, GroupJoin, Join dll.) yang masih harus dibahas. Setelah selesai, Anda dapat menggunakannya untuk docs.scala-lang.org. - person missingfaktor; 13.11.2011
comment
@soc: Terlihat jauh lebih baik dengan until. Diperbarui, terima kasih! - person missingfaktor; 13.11.2011
comment
@macias: Apa yang Anda maksud dengan itu? Hampir tidak ada yang setara dengan 1:1. - person missingfaktor; 13.11.2011
comment
@missingfaktor, saya menganggap terjemahan yang membutuhkan sesuatu yang lebih substansial daripada 1-liner bukan sebagai pemetaan 1:1. - person greenoldman; 13.11.2011
comment
@soc: Saya memperbarui jawaban saya. Anda sekarang dapat menggunakannya untuk docs.scala-lang.org. :-) - person missingfaktor; 13.11.2011
comment
@macias: Periksa jawaban yang diperbarui. Fungsi tanpa pemetaan 1:1 (sesuai definisi Anda) dijelaskan secara terpisah. - person missingfaktor; 13.11.2011
comment
@missingfaktor, bagaimana saya bisa memberi suara positif kepada Anda sebanyak +100? ;-) Sekarang, saya baru mengenal Scala tetapi menurut saya pemeriksaan ukuran kedua di SingleXX akan lebih cepat dengan coll.tail.isEmpty -- ini harusnya O(1), bukan ukuran O(n). - person greenoldman; 14.11.2011
comment
@macias: Oh, tentu saja. Seringkali saya menggunakan Vector daripada List. Oleh karena itu pengawasan. Saya akan memperbarui kode sesuai saran Anda. - person missingfaktor; 14.11.2011
comment
@macias: Saya menulis kode ini dengan mempertimbangkan antarmuka koleksi umum (seperti Traversable, Seq). Fakta bahwa size adalah operasi O(n) khusus untuk daftar, dan belum tentu berlaku untuk jenis koleksi lainnya. Saya sekarang memperbarui kodenya. - person missingfaktor; 14.11.2011
comment
Ini sangat membantu. Mereka harus membuat standar ISO untuk koleksi API. - person Dmitry Ornatsky; 08.02.2012
comment
@DmitryOrnatsky, terima kasih. :) Kita tidak perlu melakukan hal sejauh itu. Ini akan lebih dari cukup jika API Microsoft sesuai dengan nama dan konvensi umum, daripada menciptakan yang baru. - person missingfaktor; 08.02.2012
comment
Bagan Anda tidak akurat untuk Average: xs.Average(trans) salah, seharusnya trans(xs).sum / xs.length untuk tipe yang tidak dapat dibatalkan. Untuk xs.Average(): rata-rata int adalah ganda, bukan int. Selain itu, dalam kedua kasus untuk tipe nullable, null tidak dihitung. - person Vlad; 21.10.2013
comment
Selain itu, xs.Max(f) LINQ memang f(xs).max. - person Vlad; 21.10.2013
comment
Bagus sekali! Saya akan memberikan suara untuk jawaban ini sekali sehari! - person python_kaa; 15.01.2015
comment
Bagaimana dengan partition?: def partition(p: (A) ⇒ Boolean): (List[A], List[A]) Partisi koleksi traversable ini menjadi dua koleksi traversable berdasarkan predikat - person yǝsʞǝla; 06.02.2015

Saya tidak tahu apa-apa tentang C# atau LINQ, tapi apakah ini yang Anda cari?

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

Tidak ada metode untuk mendapatkan elemen atau default, tetapi ini akan berhasil:

scala> scala.util.control.Exception.allCatch.opt(l(5)) getOrElse 0
res4: Int = 0
person pr1001    schedule 12.11.2011
comment
Terima kasih tetapi saya sedang mencari terjemahan LINQ -› Scala yang lengkap, sehingga mental saya bisa berada di jalur yang benar lebih cepat. Sesuatu untuk dicetak, dibaca, dan dihafal. - person greenoldman; 12.11.2011
comment
Untuk yang terakhir, Anda bisa melakukan l.lift(5).getOrElse(0). - person missingfaktor; 12.11.2011