Rock
Rock

Reputation: 33

Number of times number appears in a 2D array

class Board
{
    int[,] ActiveXY = new int[9, 3];
    private int NumOfActiveCells()
    {     
        int counter = 0;
        for (int i = 0; i < 9; i++)
        {
            if (ActiveXY[i, 2] == 1) counter++;
        }
        return counter;
    }
...

In this code, ActiveXY is a 2D array of 9 cells, each having 3 properties: [0] is the X, [1] is the Y, and [2] is if its active or not, being 0 for inactive and 1 for active.

I'm trying to check how many cells are active with NumOfActiveCells(), and though it works, I still wish to see if there is a shorter or even a one-liner way of doing this. Perhaps something using LINQ?

EDIT: Changed "Better" => "Shorter". I explained myself incorrectly. I do agree that the code I have is just fine, but I just wanted to see if there is a shorter way, thank you for the replies!

Upvotes: 0

Views: 131

Answers (1)

Sweeper
Sweeper

Reputation: 271195

Although int[,] only implements IEnumerable (the non-generic version), you can Cast<int> to make it an IEnumerable<int>. Then you can use all the usual LINQ operations.

All the elements that you want have an index of [x, 2] (third column) in the original 2D array. Since an IEnumerable<int> represents a 1D sequence, the 2D array will be flattened and the index [x, 2] will be mapped to 3x + 2. So to check whether an element e in the 1D sequence is in the third column in the original 2D array, we just need to see if its index in the 1D sequence can be expressed as 3x + 2.

int total1s = ActiveXY.Cast<int>().Where((e, index) => e == 1 && (index + 1) % 3 == 0).Count();

Edit: I just thought of a more readable solution:

int total1s = Enumerable.Range(0, 9).Select(i => ActiveXY[i, 2]).Count(x => x == 1);

This works just like your for loop, with an "loop counter" of i going from 0 to 8, and counting the elements that match x == 1.

Upvotes: 1

Related Questions