C# LINQ for Scala heads
This is a memo of C# Linq features for Scala programmers. Or vice versa.
Type inference
C# has type inference. I try to use var when I can for local variables.
Scala also has var, but the preferred way is to use immutable val if possible.
val x = 1
Creating a new List or an Array
C# can create collections in-line.
var list = new List
All collections in Scala comes with a factory method.
val list = List("Adam", "Alice", "Bob", "Charlie")
val array = Array(0, 1, 2)
Filtering using lambda expression
C# has “enrich-my-library” monkey patching that adds Where method to a normal Array.
var xs = array.Where(x => x >= 1);
There are several ways to write this in Scala.
array.filter(x => x >= 1)
array filter { _ >= 1 }
array filter { 1 <= }
Projection
Projection in C# is done by Select and SelectMany.
These correspond to map and flatMap.
array map { _ + 1 }
array flatMap { Array(_, 3) }
Sorting
C# can sort things using OrderBy.
I can’t remember the last time I had to sort something in Scala, but you can do that using sortBy.
list sortBy { _.length }
Filtering using query expression
Now comes the query expression.
The closest thing Scala got probably is for-comprehension.
for (x <- array if x >= 1)
  yield x
You can write something similar in C#, but unlike Scala foreach does not return a value, so the whole thing needs to be wrapped in a method.
Projection using query expression
Let’s try projection to an anonymous type in C#.
Scala using for-comprehension.
for (x <- array)
  yield new { def foo = x + 1 }
Sorting by intermediate values
Here’s how to sort by intermediate values.
var results = from x in list let cs = new Regex(@"[aeiou]").Replace(x.ToLower(), “”) orderby cs.Length select x;
Scala’s for-comprehension does not support sorting, but you can always sort things afterwards.
list sortBy { x =>
  val cs = """[aeiou]""".r.replaceAllIn(x.toLowerCase, "")
  cs.length
}
Cross join
The SQL-ness comes in handy when you join with C#.
Using Scala for-comprehension.
for {
  x <- list
  c <- x.toCharArray
  if c != 'a' && c != 'e'
} yield c
Inner join
Inner joining using C#.
Using Scala for-comprehension.
for {
  name <- list
  n <- array if name.length == n + 3
} yield (name, n)
Grouping
Grouping using C#.
Not for-comprehension, but still doable in Scala.
list groupBy { _(0) } filter { case (k, vs) =>
  vs.size > 1 }
Quantifiers
Quantifiers work more or less the same way.
In Scala.
val hasThree = list exists { _.length == 3 }
val allThree = list forall { _.length == 3 }
Pattern matching
One unique aspect of Scala is that it accepts a partial function where a lambda expression is expected.
array map {
  case 1 => "foo"
  case n if n % 2 == 0 => n.toString + "!"
}
You probably have to throw an exception to mimic this in C#.
Notes
For Scala I prefer normal calls to filter and map over for-comprehension. Infix operator syntax and placeholder syntax makes array filter { _ >= 1 } concise enough that for-comprehension ends up becoming more bulkier unless they are nested.
On the other hand in C#, query expression syntax rids of some of the symbols (., (), =>) from fluent syntax.
Rahul (@missingfaktor) wrote a nice list of Enumerable methods and their equivalent ones in Scala, which covers everything I couoldn’t here.