xhroot

LINQPad Snippets

Joseph Albahari’s LINQPad is a great tool for quick and easy C#/LINQ experimentation. (Yes, that Albahari.) Rather than fire up a separate Visual Studio instance and create a console project, just start LINQPad. As the name suggests, it’s well suited for exploring LINQ queries and data transformations but it also functions well as a C# REPL. It’s especially handy for trying out a custom string.Format, regex grouping or reflection expression.

The code in this post is a diversion from conventional best-practice. This is largely an annotated dump of some of my saved LINQPad queries, in some cases merely products of curiosity. Consider this a disclaimer.

Prime Numbers

When composing a LINQ query, I’ve often been impressed with how expressive it can be. For example, this returns a list (IEnumerable, actually) of all prime numbers up to 100:

1
Enumerable.Range(2, 99).Where(i => !Enumerable.Range(2, i-2).Any(j => i % j == 0))

I started with nested for loops which reduced to two Ranges. There are even some prime sieves out there that are not much longer than this.

Fizz Buzz

Seems like everyone’s got a fizzbuzz implementation lying around somewhere. Here’s my code golfed version:

1
Enumerable.Range(1,30).Aggregate("",(a,n)=>a+(n%15==0?"fizzbuzz":n%3==0?"fizz":n%5==0?"buzz":n.ToString())+"\n")

Word Frequency

Underscore.js brings much needed functional programming utilities to javascript. One example counts the word frequency in a song:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var lyrics = [
  {line : 1, words : "I'm a lumberjack and I'm okay"},
  {line : 2, words : "I sleep all night and I work all day"},
  {line : 3, words : "He's a lumberjack and he's okay"},
  {line : 4, words : "He sleeps all night and he works all day"}
];

_.chain(lyrics)
  .map(function(line) { return line.words.split(' '); })
  .flatten()
  .reduce(function(counts, word) {
    counts[word] = (counts[word] || 0) + 1;
    return counts;
}, {}).value();

=> {lumberjack : 2, all : 4, night : 2 ... }

Compare it to a LINQ version:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Count words in a song. LINQ version of http://underscorejs.org/#chaining.
var lyrics = new[] {
  new { line = 1, words = "I'm a lumberjack and I'm okay" },
  new { line = 2, words = "I sleep all night and I work all day" },
  new { line = 3, words = "He's a lumberjack and he's okay" },
  new { line = 4, words = "He sleeps all night and he works all day" },
};

// map, flatten, reduce.
lyrics
  .Select(line => { return line.words.Split(' '); })
  .SelectMany(line => line)
  .Aggregate(new Dictionary<string, int>(), (counts, word) => {
    counts[word] = (counts.ContainsKey(word) ? counts[word] : 0) + 1;
    return counts;
  }).Dump();

Pretty close to 1:1, thanks to anonymous types. If anything, this shows you how versatile Underscore.js is. That aside, I think this is more LINQish:

1
2
3
4
5
lyrics.SelectMany(verse => verse.words.Split(' '))
  .GroupBy(word => word, (word, grp) =>
      new KeyValuePair<string, int>(word, grp.Count()))
  .ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
  .Dump();

The variable name “verse” was used to avoid confusion with the anonymous property “line”, which is never used.

Boolean Trivia

In one project, I had to convert a string to a bool. Fiddling around in LINQPad, I arrived at this construct:

1
2
// If "true" (or "True"), return true. Anything else is false.
bool maybe = bool.TryParse(stringBool, out maybe) && maybe;

This one-liner evaluates any string stringBool as true if it is “True” or “true” (or “tRue”, etc.), but false if anything else. What’s interesting is that it is declaring a boolean variable, referencing it as an out parameter, reading it, and reassigning to it in one statement. As an exercise, how would you make one change to reverse the logic: every string is true except an explicit “false” or “False”?

Fortunately, I left none of this ambiguity in and at the end of the day, simply used:

1
bool maybe = "true".Equals(stringBool, StringComparison.OrdinalIgnoreCase);

Conditional Operator Abuse

How about a statement that chooses between two functions to execute using the conditional operator?

1
(true ? (Action)(() => Console.Write("Yes.")) : () => Console.Write("No."))();

The Action cast tells the compiler what kind of lambda is being used. The second expression can infer the same type and omits the cast. Since the expression will evaluate to a single Action, it needs to be executed with the (). It’s possible to pass in a parameter:

1
2
3
4
5
6
var mode = "DEBUG";
var error = "Error: An error occurred.";
(mode == "DEBUG"
  ? (Action<string>)(msg => Debug.Write(msg))
  : msg => Console.Write(msg)
)(error);

If you’re wincing at this, can’t say I blame you.

A Shorter Guid

This one might actually be useful. Every so often I need a unique identifier so I turn to C#’s Guid class. After a while, I began thinking of ways to compress that 32 char guid down a tad and after some experimenting, came up with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Create base 62 guids. Converts 32 char guid into base 62 alphabet.

var base16alphabet = "0123456789abcdef";
var base62alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

var guid = Guid.NewGuid().ToString().Replace("-","");
var dec = new BigInteger(0);

// Convert hex guid to decimal.
for (int i=0; i < guid.Length; i++)
{
  dec += new BigInteger(base16alphabet.IndexOf(guid[guid.Length - 1 - i]))
    * new BigInteger(Math.Pow(16, i));
}

// Convert decimal to base 62.
var quotient = dec;
string base62num = "";
BigInteger remainder;
while (quotient > 0)
{
  remainder = quotient % 62;
  base62num = base62alphabet[(int)remainder] + base62num;
  quotient /= 62;
}

string.Format("{0} (b16) = {1} (b62)", guid, base62num).Dump();

When executed in LINQPad, you should see something like this:

1
1a652d41d3fd4ccc8e98981f2ff552dc (b16) = NO2nH1Hh1DqsNeOk784HO (b62)

32 characters can be represented in a 23 character, URL-friendly, globally unique string.


I encourage you to download LINQPad, play around, discover interesting little corners of C# and LINQ, and build your own snippets library. This was a long post so thanks for sticking around to the end, apologies to Matt Damon, but we’re out of time.

Comments