Is there an elegant way to count how many values are positive in a datatable without having to go through every element and check it? I've looked at DataTable.Compute method and some LINQ examples too but they all require a column name and I need it for the whole table.
Try this :
No need (for the code) to know the column names :
dt.AsEnumerable().Select(row1 => dt.Columns.Cast<DataColumn>()
.ToDictionary(column => column.ColumnName, column => row1[column.ColumnName]))
.SelectMany(f=>f.Values)
.Count(f=>decimal.Parse(f.ToString())>0);
Example :
6 positive :
Have you considered using DataTable.Select?
int TotalPositiveValues = 0;
foreach (DataColumn NextColumn in MyDataTable.Columns)
{
DataRow[] PositiveRows = MyDataTable.Select(NextColumn.ColumnName + " >=0");
int TotalPositiveValues += PositiveRows.Length;
}
EDIT: provided all values in your DataTable qualify as numbers.
Related
C#:
I have a datatable with a variable number of columns - returned by calling a stored procedure.
and I would like to convert it to Dictionary key-value pairs (string).
How do I achieve this without having to iterate through each column in each row? I won't know how many columns are there in the datatable at any time.
Thanks
G
You said your result should contain values for the first (and only) row of the dataTable
This one liner can do the trick
var res = dt.Columns.Cast<DataColumn>().ToDictionary(col => col.ColumnName, col=>dt.Rows[0][col]);
ToDictionary will internally enumerate the columns
But I really prefer this explicit enumeration:
var row = dt.Rows[0];
var res2 = new Dictionary<string, object>();
foreach (DataColumn col in dt.Columns)
res2.Add(col.ColumnName, row[col]);
The second is much more readable IMHO.
You can use a method like this calling the extension method ToDictionary() :
internal Dictionary<string,object> GetDict(DataTable dt)
{
return dt.AsEnumerable()
.ToDictionary(row => row.Field<string>(0),
row => row.Field<object>(1));
}
This question already has answers here:
Remove Single Quotes From All Cells in a DataTable - Creating New Table - Using LINQ in Vb.Net
(2 answers)
Closed 3 years ago.
How to replace double quotes of all rows of DataTable using Linq in C#?
I tried below but I need more optimized code for same purpose
int columnIndex = 0;
dtExcelData.Rows.RemoveAt(0);
foreach (DataColumn excelSheetColumns in dtExcelData.Columns)
{
int rowIndex = 0;
foreach (DataRow row in dtExcelData.Rows)
{
dtExcelData.Rows[rowIndex][columnIndex] = dtExcelData.Rows[rowIndex][columnIndex].ToString().Replace("\"", "");
rowIndex++;
}
columnIndex++;
}
Please suggest
You could make use of DataRow.ItemArray. For example
foreach(var row in dtExcelData.Rows.Cast<DataRow>())
{
row.ItemArray = row.ItemArray.Select(x=>x.ToString().Replace("\"","")).ToArray();
}
You should
be aware you remove the first row, if you write results back to your data store you will lose this row.
ask yourself why you iterare over Columns and rows if you never use the objects. Why don't you simply use a for loop over rowIndex and columnIndex.
think about only processing data fields that really are a string.ToString() turns everything into a string, then you overwrite any kind of data field type with a string. Better test for "is String" and then cast the field into (String).
think about getting every row, then process every column in this row. This could be faster to execute, but even if it isn't then still is more understandable (at least to me).
I have added code here because code is better other than URL, You can try this below code:
That is already mentioned in below URL
Remove Single Quotes From All Cells in a DataTable - Creating New Table - Using LINQ in Vb.Net
dtExcelData.Rows.RemoveAt(0);
DataTable clone = dtExcelData.Clone();
string t;
var qry = from DataRow row in dtExcelData.Rows
let arr = row.ItemArray
select Array.ConvertAll(arr, s =>
(t = s as string) != null
&& t.StartsWith("\"")
&& t.EndsWith("\"") ? t.Trim('\"') : s);
foreach (object[] arr in qry)
{
clone.Rows.Add(arr);
}
Could anyone tell me please what the best/most efficient way is to get the index of the row in a datagrid view that has the smallest integer value for a particular column.
I did this using a foreach loop to traverse the collection of rows and compare the respective value of each row and store the smallest. Each time I find a smaller value I update my "smallest" variable with that value. This works but I'm pretty sure there must be some lambda expression that does a better job. Could anyone help please?
This is the column containing the value:
dgvItems.Rows[i].Cells["col1"].Value
Many thanks.
the best way to do so is with LINQ queries,
LINQ is better looking, more readable and more efficient than for loops
you should use the DataGridView data source and not directly to the DataGridView data
DataTable dt = dgv.DataSource as DataTable;
MinRow: var result = dt.Rows.IndexOf(dt.AsEnumerable().OrderBy(x => x["col1"]).First());
MaxRow: var result1 = dt.Rows.IndexOf(dt.AsEnumerable().OrderByDescending(x => x["col1"]).First());
hope this could help you
I will help you for this one since you are not asking about using LINQ.
Lets do it the "usual" way..
First, declare a new List
List<int> columnValue = new List<int>();
we will Iterate through each row in the grid
foreach (DataGridViewRow row in myDataGrid.Rows)
{
if (null != row && null != row.Cells["col1"].Value)
{
//Add the value of columnValue to list
columnValue.Add(Convert.ToInt32(row.Cells[0].Value.ToString()));
}
}
and get the MIN. value from LIST
int result = columnValue.Min();
finally, get the index of the value we got from the LIST
int i = columnValue.IndexOf(result); //returns the Index from "result" var
I'm trying to perform the C# equivalent of Select * where [columnname] = [value]. I began with a foreach loop to iterate through the table row by row, however I had forgotten that one cannot access a column via row.column["<colname>"].
How do I achieve this objective? Most of the examples I have seen target one specific row with the intention of casting it's value to a string, however my task is to move all entries with a value of DateTime == < DateTime.Today to an archived table.
Can I continue with the following code? Or am I approaching this in the wrong manner?
void archiveDates()
{
foreach (DataRow row in workingupdates.storageTable.Rows)
{
//target DateTime column here
}
}
You can use the Field extension method that is strongly typed and also supports nullable types. You have an overload for the index, name or the DataColumn(among others):
foreach (DataRow row in workingupdates.storageTable.Rows)
{
DateTime dt = row.Field<DateTime>("columnname");
}
If you instead want to find all rows where the date column has a specific value you can use Linq-To-DataTable:
var matchingDataRows = workingupdates.storageTable.AsEnumerable()
.Where(row => row.Field<DateTime>("columnname") == dateTimeVariable);
Now you can simply enumerate this query:
foreach (DataRow row in matchingDataRows)
{
// ...
}
Or create a collection like
a DataRow[] with matchingDataRows.ToArray() or
a List<DataRow> with matchingDataRows.ToList()
a new DataTable with matchingDataRows.CopyToDataTable()
Note that you have to add System.Linq; to the top of the file.
Best practice when converting DataColumn values to an array of strings?
[Edit]
All values for certain DataColumn for all DataTable rows to be converted to an array of string?
If I understood your goal you want to specify a particular column and return all its values as a string array.
Try these approaches out:
int columnIndex = 2; // desired column index
// for loop approach
string[] results = new string[dt.Rows.Count];
for (int index = 0; index < dt.Rows.Count; index++)
{
results[index] = dt.Rows[index][columnIndex].ToString();
}
// LINQ
var result = dt.Rows.Cast<DataRow>()
.Select(row => row[columnIndex].ToString())
.ToArray();
You could replace columnIndex with columnName instead, for example:
string columnName = "OrderId";"
EDIT: you've asked for a string array specifically but in case you're flexible about the requirements I would prefer a List<string> to avoid the need to determine the array length prior to the for loop in the first example and simply add items to it. It's also a good opportunity to use a foreach loop instead.
I would then rewrite the code as follows:
List<string> list = new List<string>();
foreach (DataRow row in dt.Rows)
{
list.Add(row[columnIndex].ToString());
}
DataRow.ItemArray Property -
http://msdn.microsoft.com/en-us/library/system.data.datarow.itemarray.aspx
Also, which version are you using? You should check out the DataTableExtensions class -
http://msdn.microsoft.com/en-us/library/system.data.datatableextensions.aspx
And the DataRowExtensions class -
http://msdn.microsoft.com/en-us/library/system.data.datarowextensions.aspx
I know this question is old, but I found it in my Google search trying to do something similar. I wanted to create a list from all the values contained in a specific row of my datatable. In my code example below, I added a SQL datasource to my project in Visual Studio using the GUI wizards and I dropped the needed table adapter into the designer.
'Create a private DataTable
Private authTable As New qmgmtDataSet.AuthoritiesDataTable
'Fill the private table using the table adapter
Me.AuthoritiesTableAdapter1.Fill(Me.authTable)
'Make the list of values
Dim authNames As List(Of String) = New List(Of String)(From value As qmgmtDataSet.AuthoritiesRow In Me.authTable.Rows Select names.authName)