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;
}
}
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: