在Scala中IEnumerable LINQ等价物的图表?

可能重复:
LINQ类似于Scala

我正在寻找图表,它显示了IEnumerable的LINQ方法的Scala中的等价物:

  • 首先是头
  • select是地图
  • SingleOrDefault是…(我不知道)
  • … 等等

有谁知道这样的“翻译”表的任何东西?

我只列出了来自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)`. 

有一些function没有直接的等价物,但是推出自己的function相当简单。 这里有一些这样的function。

单身

 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 } 

join

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

小组join

 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. 在惯用的Scala中,总体function通常优于部分function。 因此, singlesingleOrDefault惯用实现会产生一个types的值,不是A Either[Exception, 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. Scalaz的Zero / mzero与C#的default值机制不太一样。 有关详细信息,可以参考我后面在这个主题上写的这篇文章。

  3. 您可以使用丰富我的库模式来实现与C#的扩展方法相同的效果。 有关详细信息,请参阅此部分 。

我不知道什么关于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