Scala中IEnumerable LINQ等价物的图表? [复制]
Posted
技术标签:
【中文标题】Scala中IEnumerable LINQ等价物的图表? [复制]【英文标题】:Chart of IEnumerable LINQ equivalents in Scala? [duplicate] 【发布时间】:2011-12-27 15:18:42 【问题描述】:可能重复:LINQ analogues in Scala
我正在寻找在 Scala 中显示 IEnumerable 的 LINQ 方法等价物的图表:
首先是头部 选择地图 SingleOrDefault 是...(我不知道) ...等等有人知道这种“翻译”表吗?
【问题讨论】:
为什么不满足于 LINQ for Scala(完整的 API 重新实现):github.com/nicholas22/propelS @casperOne:为什么不合并两个线程? 这个问题与另一个问题相去甚远。这个问题更加集中和具体,而另一个问题则比较模糊。两者都有效且不同。 我不同意重复评估。这是完全不同的,更有帮助。 【参考方案1】:我只列出了 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)
注意事项:
在惯用的 Scala 中,总体函数通常优于部分函数。因此,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)
Scalaz 的 Zero
/mzero
与 C# 的 default
值机制不太一样。详情可以参考我前段时间写的this帖子。
您可以使用enrich-my-library 模式来实现与C# 的扩展方法相同的效果。详情请参阅this 和this。
【讨论】:
非常感谢!!!更新时,如果没有1:1映射,请直接写成“没有1:1”映射,先谢谢了。 第三个Aggregate
不正确。 trans(xs.foldLeft(seed)(accumFunc))
是正确的。
@missingfaktor:是否可以将该列表用于 docs.scala-lang.org?
这非常有用。他们必须为收集 API 创建一个 ISO 标准。
太棒了!我会每天为这个答案投票一次!【参考方案2】:
我对 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
【讨论】:
谢谢,但我正在寻找完整的 LINQ -> Scala 翻译,因此我可以在精神上更快地走上正轨。可以打印、阅读和记忆的东西。 对于最后一个,您可以使用l.lift(5).getOrElse(0)
。以上是关于Scala中IEnumerable LINQ等价物的图表? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
NET问答: JS 中有 LINQ SelectMany 方法的等价实现吗?
Observable.Do 等价于 Enumerable [重复]
LINQ 的具体程度如何。包含 IEnumerable 结果?
C# LINQ 优雅地将 IEnumerable<IGrouping> 转换为 IEnumerable<IEnumerable>?