2011-11-12 23 views
48

thể trùng lặp:
LINQ analogues in ScalaBiểu đồ về tương đương LINQ IEnumerable trong Scala?

Tôi đang tìm kiếm biểu đồ trong đó cho thấy các khoản tương đương trong Scala các phương pháp LINQ cho IEnumerable:

  • Đầu tiên là người đứng đầu
  • Chọn là bản đồ
  • SingleOrDefault là ... (Tôi không biết)
  • ... và vân vân

Có ai biết bất cứ điều gì của "dịch" bảng như vậy?

+1

Tại sao giải quyết cho bất cứ điều gì ít hơn LINQ cho Scala (full API tái thực hiện): https://github.com/nicholas22/propelS – Scooterville

+4

@casperOne: Tại sao không hợp nhất hai đề? – missingfaktor

+5

Câu hỏi này không ở đâu gần trùng lặp với câu hỏi khác. Câu hỏi này tập trung hơn và cụ thể hơn, trong khi câu hỏi còn lại là mơ hồ. Cả hai đều hợp lệ và khác nhau. –

Trả lời

121

tôi chỉ liệt kê ra các khoản tương đương các chức năng từ Enumerable<A>. Điều này chưa hoàn chỉnh kể từ bây giờ. Tôi sẽ cố gắng cập nhật điều này sau với nhiều hơn.

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

Không có tương đương trực tiếp của một số chức năng, nhưng nó khá dễ dàng để cuộn của riêng bạn. Dưới đây là một số chức năng như vậy.

Độc:

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 
} 

Tham:

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

GroupJoin:

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

Ghi chú:

  1. Trong thành ngữ Scala, tổng các chức năng thường được ưa thích hơn các chức năng một phần. Do đó, việc triển khai thành ngữ của singlesingleOrDefault sẽ tạo ra một giá trị loại Either[Exception, A] thay vì A. Ví dụ: đây là triển khai tinh tế của single trả về 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. Scalaz của Zero/mzero là không hoàn toàn giống như cơ chế giá trị default C# 's. Để biết chi tiết, bạn có thể tham khảo this bài đăng tôi đã viết về chủ đề này một thời gian trước.

  3. Bạn có thể sử dụng mẫu làm giàu thư viện của tôi để đạt được hiệu quả tương tự như phương pháp mở rộng của C#. Tham khảo thisthis để biết chi tiết.

+1

Cảm ơn bạn rất nhiều !!! Khi cập nhật, nếu không có ánh xạ 1: 1, chỉ cần đặt nó là ánh xạ "không 1: 1", cảm ơn bạn trước. – greenoldman

+0

'Tổng hợp' thứ ba không chính xác. 'trans (xs.foldLeft (seed) (accumFunc))' là đúng. –

+0

@missingfaktor: Có thể sử dụng danh sách đó cho docs.scala-lang.org không? – soc

0

Tôi không biết gì về C# hoặc LINQ, nhưng đây có phải là những gì bạn đang tìm kiếm không?

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 

Không có phương pháp để có được một thành phần hoặc một mặc định, nhưng điều này sẽ làm việc:

scala> scala.util.control.Exception.allCatch.opt(l(5)) getOrElse 0 
res4: Int = 0 
+0

Cảm ơn bạn nhưng tôi đang tìm kiếm LINQ -> bản dịch Scala hoàn chỉnh, vì vậy tôi có thể tinh thần được đi đúng hướng nhanh hơn. Một cái gì đó để in, đọc và ghi nhớ. – greenoldman

+3

Đối với điều cuối cùng, bạn có thể đã thực hiện 'l.lift (5) .getOrElse (0)'. – missingfaktor

Các vấn đề liên quan