Scala 中 IEnumerable LINQ 等效项的图表?[复制]

Chart of IEnumerable LINQ equivalents in Scala? [duplicate]

提问人:greenoldman 提问时间:11/12/2011 最后编辑:Communitygreenoldman 更新时间:2/7/2019 访问量:10325

问:

这个问题在这里已经有答案了:
11年前关闭。

可能的重复项:
Scala 中的 LINQ 类似项

我正在寻找图表,该图表显示了 Scala 中 IEnumerable 的 LINQ 方法的等效项:

  • 首先是头部
  • 选择地图
  • SingleOrDefault 是 ...(我不知道)
  • ...等等

有谁知道这样的“翻译”表?

C# LINQ Scala IEnumerable 可迭代

评论

1赞 Scooterville 6/10/2012
为什么要满足于 LINQ for Scala(完整的 API 重新实现):github.com/nicholas22/propelS
4赞 missingfaktor 7/22/2012
@casperOne:为什么不合并这两个线程呢?
7赞 Mauricio Scheffer 7/24/2012
这个问题绝不是另一个问题的重复。这个问题更加集中和具体,而另一个问题则更加模糊。两者都有效且不同。
3赞 vsnyc 10/25/2015
我不同意重复评估。这是完全不同的,更有帮助。

答:

0赞 pr1001 11/12/2011 #1

我对 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

评论

0赞 greenoldman 11/13/2011
谢谢你,但我正在寻找完整的 LINQ -> Scala 翻译,这样我就可以在精神上更快地走上正轨。打印、阅读和记忆的东西。
3赞 missingfaktor 11/13/2011
对于最后一个,你可以做.l.lift(5).getOrElse(0)
135赞 17 revs, 5 users 71%missingfaktor #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)
}

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

注意

  1. 在惯用的 Scala 中,总函数通常优先于部分函数。因此,惯用的 and 实现将产生 type 的值,而不是 。例如,这里是 return 的优化实现。singlesingleOrDefaultEither[Exception, A]AsingleEither[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# 的值机制并不完全相同。有关详细信息,您可以参考我前段时间写的关于此主题的这篇文章。Zeromzerodefault

  3. 您可以使用 enrich-my-library 模式来达到与 C# 的扩展方法相同的效果。有关详细信息,请参阅此和

评论

1赞 greenoldman 11/13/2011
谢谢!!!更新时,如果没有 1:1 映射,请直接设置为“无 1:1”映射,提前感谢您。
0赞 Daniel C. Sobral 11/13/2011
第三个是不正确的。 是恰当的。Aggregatetrans(xs.foldLeft(seed)(accumFunc))
0赞 soc 11/13/2011
@missingfaktor:是否可以将该列表用于 docs.scala-lang.org?
7赞 Dmitry Ornatsky 2/8/2012
这是非常有帮助的。他们必须为集合 API 创建 ISO 标准。
2赞 python_kaa 1/15/2015
非常好!我会每天为这个答案投一次赞成票!