Replace List.foreach with LINQ

I am new to LINQ and am doing some experimentation with it.

Sorry if this is a duplicate, but I cannot find a suitable guide (for me)

I want to replace this code:

DataTable table List<string> header = new List<string>(); table.Columns.Cast<DataColumn>().ToList().ForEach(col => header.Add(col.ColumnName)); 

with something LINQ like:

 var LINQheader = from mycol in table.Columns select mycol.ColumnName; LINQheader.tolist(); 

but it doesn't even compile. what I want This is not a one-line solution, but I would like some logic to understand how to build it in more complex environments (for example, choosing many nodes in XML with some logic)

+5
source share
6 answers

here is the source code

 table.Columns.Cast<DataColumn>().ToList().ForEach(col => header.Add(col.ColumnName)); 

Why is Cast used?
because it allows you to handle DataColumnCollection elements as a DataColumn not an object.

Why is ToList used?
because it converts your IEnumerable to List and allows you to call ForEach , because this function is a special method that exists in the List class.

Why is ForEach used?
because it allows you to do what you want for each item in the list (in your case, it adds the column name of each column to another list ( header )).

Simplified version:

Now suppose you want to add column names to the header , where they begin with "Student", you can write something like this

 DataTable table = new DataTable(); List<string> header = new List<string>(); foreach (DataColumn col in table.Columns) { if (col.ColumnName.StartsWith("Id")) // you can remove this line if you want to add all of them header.Add(col.ColumnName); } 

you can also use this

 table.Columns.Cast<DataColumn>() .ToList() .ForEach(col => { if (col.ColumnName.StartsWith("Id")) header.Add(col.ColumnName) }); 

or

 var headers = table.Columns.Cast<DataColumn>() .Where(col => col.ColumnName.StartsWith("Id")) .Select(col => col.ColumnName); header.AddRange(headers); 
+3
source

You can use Enumerable.Aggregate() to do this:

 var header = table.Columns.Cast<DataColumn>().Aggregate(new List<string>(), (list, col) => { list.Add(col.ColumnName); return list; }); 

In general, Linq allows you to extract and transform sequences of data from data sources. What you want to do on this question is to iterate over the sequence and return an immediate result. This is not Linq's main focus, but there are methods that perform tasks like this , including Aggregate() , Average() , Count() , Max() , etc.

+3
source
 var LINQheader = from mycol in table.column select mycol.ColumnName; LINQheader.tolist(); 

This will not compile since the DataTable does not have such a property as a column , only Columns exist, and you should use the .Cast() method, since they do not implement the right interface (see @Uriil answer).

Try the following:

 var LINQheader = from mycol in table.Columns.Cast<DataColumn>() select mycol.ColumnName; LINQheader.tolist(); 

If you want to use it in an extension method, you can do it like this:

 public static IEnumerable<string> GetHeaderColumns (this DataTable dataTable) { if (dataTable == null || !dataTable.Columns.Any()) { yield break; } foreach (var col in dataTable.Columns.Cast<DataColumn>()) { yield return col.ColumnName; } } 
+2
source
  static void Main(string[] args) { DataTable tbl = new DataTable(); tbl.Columns.Add("A"); tbl.Columns.Add("B"); var p = from DataColumn col in tbl.Columns select col.ColumnName; foreach(string a in p) { Console.WriteLine(a); } } 

Here is an example of a little code. If you want to be a List<string> , use ToList() .

EDIT:

Like @Grundy, you did not specify a col type, which is a DataColumn.

 List<string> columnList = (from DataColumn mycol in table.Columns select mycol.ColumnName).ToList(); 

Here it will be your one line.

+2
source

Why not just choose

 DataTable table; IEnumerable<string> header = from mycol in table.Columns.Cast<DataColumn>() select mycol.ColumnName; 
+1
source

You have some issues requiring a workaround:

  • ForEach is a list-listing method, so it cannot convert it to LINQ
  • LINQ is for data selection, aggregation, but not for data modification
  • table.Columns , returns a DataColumnCollection that we don’t implement IEnumerable<T> , so you still have to jot it down:

     var LINQheader = from mycol in table.Columns.Cast<DataColumn>() select name.ColumnName; 
+1
source

Source: https://habr.com/ru/post/1210090/


All Articles