Search code examples
c#countdatagridviewnumberslabel

count DataGridView cells with equal values


I have a DataGridView that receives a list of lottery numbers, I would like to count how many times the same number appeared in the grid list, I have an image for example, I am using this code. enter image description here

private void calculaTotalGrid()
    {
        ResultadoNumeros numer = new ResultadoNumeros();
        int badCount = dgLista.Rows.Cast<DataGridViewRow>().Where(row => row.Cells[2].Value.ToString() == "01").Count();
        lbl_01.Text = badCount.ToString();
    } 

          int val;
        int valToCount = 10;
        int count = 0;
        foreach (var row in dgLista.Rows.Cast<DataGridViewRow>())
            foreach (var cell in row.Cells.Cast<DataGridViewCell>())
                count += int.TryParse(cell.Value?.ToString(),
                    out  val) && val == valToCount ? 1 : 0;
                       txtNum.Text = count.ToString();

Could someone help me or give me a light on how to do this? minha class ResultadoNumeros

public int concurso { get; set; }
    public int _01 { get; set; }
    ----
    public int _15 { get; set; }

class

public static DataTable ObterNumeros()
    {
        DataTable tabela = new DataTable();
        DALConexao conexao = new DALConexao(DadosDaConexao.StringDaConexao);
         SqlCommand cmd = new SqlCommand();
          cmd.Connection = conexao.ObjetConexao;
            SqlDataAdapter da = new SqlDataAdapter("Select * from TBLotofacil ORDER BY Concurso DESC", conexao.StringConexao);
             da.Fill(tabela);
        return tabela;
    }        
}

Solution

  • Many ways to solve this problem. The simplest is to traverse the grid's .Rows and their .Cells to count the occurrence of the given value.

    private void calculaTotalGrid()
    {
        int valToCount = 10;
        int count = 0;
    
        foreach (var row in dgLista.Rows.Cast<DataGridViewRow>())
            foreach (var cell in row.Cells.Cast<DataGridViewCell>())
                count += int.TryParse(cell.Value?.ToString(), out int val) &&
                    val == valToCount ? 1 : 0;
    
        txtNum.Text = count.ToString();
    }
    

    Or, execute a Linq query to flatten the grid's cells into a sequence and count the cells of the given value.

    var count = dgLista.Rows.Cast<DataGridViewRow>()
        .SelectMany(r => r.Cells.Cast<DataGridViewCell>()
        .Where(c => int.TryParse(c.Value?.ToString(), out int val) && val == valToCount))
        .Count();
    

    Or, use the Enumerable.Aggregate method instead.

    var count = dgLista.Rows.Cast<DataGridViewRow>()
        .Aggregate(0, (total, row) => total += row.Cells
        .Cast<DataGridViewCell>()
        .Count(c => c.Value != null && int.Parse(c.Value.ToString()) == valToCount));
    

    According to your last revision and comments, you need to get the count of the distinct values starting from column 1 (concurso column is not included). If so, I suggest a one-liner Linq query to group the cells by their unique values and create a Dictopnary<int, int> instead of the ResultadoNumeros class. This way, you don't need to repeat one of the previous solutions for each value.

    private Dictionary<int, int> ResultadoNumeros;
    
    private void calculaTotalGrid()
    {
        int outVal = 0;
        ResultadoNumeros = dgLista.Rows.Cast<DataGridViewRow>()
            .SelectMany(r => r.Cells.Cast<DataGridViewCell>()
            .Where(c => c.ColumnIndex > 0 && int.TryParse(c.Value?.ToString(), out outVal)))
            .GroupBy(c => int.Parse(c.Value.ToString()))
            .ToDictionary(x => x.Key, x => x.Count());
    
        foreach (var kvp in ResultadoNumeros)
            Console.WriteLine($"{kvp.Key} -> {kvp.Value}");
    }
    

    To get the count of value 15 for example:

    int count15 = ResultadoNumeros[15];
    

    Or call the TryGetValue method to avoid throwing the KeyNotFoundException if the dictionary does not contain a given Key.

    int outVal = 0;
    
    if (ResultadoNumeros.TryGetValue(15, out outVal))
        Console.WriteLine(outVal);
    

    See also: