2011-11-12 11 views
48

Eventuali duplicati:
LINQ analogues in ScalaGrafico di equivalenti LINQ IEnumerable in Scala?

Cerco grafico che mostra gli equivalenti a Scala dei metodi di LINQ per IEnumerable:

  • In primo luogo è la testa
  • Select è mappa
  • SingleOrDefault è ... (non so)
  • ... e così via

Qualcuno sa niente di tale tabella "tradurre"?

+1

perché accontentarsi di niente di meno che LINQ per Scala (pieno API reimplementazione): https://github.com/nicholas22/propelS – Scooterville

+4

@casperOne: Perché non unire i due fili? – missingfaktor

+5

Questa domanda non è neanche lontanamente un duplicato dell'altro. Questa domanda è molto più focalizzata e concreta, mentre l'altra è più vaga. Entrambi sono validi e diversi. –

risposta

121

sto solo elencando gli equivalenti di funzioni da Enumerable<A>. Questo è incompleto al momento. Cercherò di aggiornarlo più tardi con altro.

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

Non esiste un equivalente diretto di alcune funzioni, ma è abbastanza facile da rotolare il proprio. Ecco alcune di queste funzioni.

singolo:

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 
} 

registrazione:

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

Note:

  1. In idiomatica Scala, funzioni totali sono generalmente preferiti funzioni parziali. Pertanto, l'implementazione idiomatica di single e singleOrDefault produrrebbe un valore di tipo Either[Exception, A] anziché A. Ad esempio, ecco l'implementazione perfezionata di single che restituisce 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. di Zero/mzero non sono abbastanza uguale meccanismo di C# 's default valore Scalaz. Per i dettagli, è possibile fare riferimento al post this che ho scritto su questo argomento qualche tempo fa.

  3. È possibile utilizzare il pattern arricchisci la mia libreria per ottenere lo stesso effetto dei metodi di estensione di C#. Fare riferimento a this e this per i dettagli.

+1

Grazie mille !!! Durante l'aggiornamento, se non esiste una mappatura 1: 1, per favore inseriscilo come mappatura "no 1: 1", grazie in anticipo. – greenoldman

+0

Il terzo 'Aggregato' non è corretto. 'trans (xs.foldLeft (seed) (accumFunc))' è corretto. –

+0

@missingfaktor: Sarebbe possibile usare quell'elenco per docs.scala-lang.org? – soc

0

Non so nulla di C# o LINQ, ma è questo quello che stai cercando?

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 

Non c'è metodo per ottenere un elemento o un default, ma questo funzionerà:

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

Grazie, ma sto cercando LINQ completo -> traduzione Scala, quindi potrei essere mentalmente sulla giusta strada più veloce. Qualcosa da stampare, leggere e memorizzare. – greenoldman

+3

Per quello ultimo, avresti potuto fare 'l.lift (5) .getOrElse (0)'. – missingfaktor

Problemi correlati