Learner
Learner

Reputation: 3396

For loops into LINQ... possible?

I have the following code which counts the appearances of cards based on type:

// counters initialization
var counters = new Dictionary<int, int>();
for (int i = 2; i <= 14; i++)
  counters.Add(i, 0);

// loop through and count number of appearances
for (int i = 0; i < playerCards.Length; i++)
  counters[playerCards[i]]++;

// Eg output: 
// playerCards = { 9, 9, 3, 3, 10 }
// counters = ( (2, 0) , (3, 2) , (4, 0) , (5, 0) , (6, 0) , (7, 0) , 
//              (8, 0) , (9, 2) , (10, 1), (11, 0), (12, 0), (13, 0), (14, 0) )

Is there a solution for this with LINQ?

Upvotes: 1

Views: 100

Answers (3)

Enigmativity
Enigmativity

Reputation: 117029

This works quite well:

var playerCards = new [] { 9, 9, 3, 3, 10 };

var lookup = playerCards.ToLookup(x => x);

var counters = Enumerable.Range(2, 13)
    .ToDictionary(x => x, x => lookup[x].Count());

I got this result:

counters

If you're happy to forgo the lookup, then this will work too:

var counters = Enumerable.Range(2, 13)
    .ToDictionary(x => x, x => playerCards.Count(y => y == x));

Upvotes: 2

Lee
Lee

Reputation: 144126

var counters = Enumerable.Range(2, 13)
    .GroupJoin(playerCards, i => i, c => c, (i, cs) => new { Counter = i, Count = cs.Count() })
    .ToDictionary(p => p.Counter, p => p.Count);

Upvotes: 2

carlpett
carlpett

Reputation: 12583

Faster? No. LINQ will seldom make your code faster, unless you can benefit from parallelization or lazy evaluation.

Often, the main benefit will be that your code will be easier to read (subjective, perhaps). But in this case, I think your code is about as clear as it can be. Converting it to LINQ will not make it faster, nor more readable.

Upvotes: 5

Related Questions