Coverage Dictionary List in DataTable

We are currently doing this by sorting through each value of the list and dictionary:

private DataTable ChangeToDictionary(List<Dictionary<string,int>> list) { DataTable datatTableReturn = new DataTable(); if (list.Count() > 0) { Dictionary<string, int> haeders = list.ElementAt(0); foreach (var colHead in haeders) { datatTableReturn.Columns.Add(colHead.Key); } } foreach (var row in list) { DataRow dataRow = datatTableReturn.NewRow(); foreach (var col in row) { dataRow[col.Key] = col.Value; } datatTableReturn.Rows.Add(dataRow); } return datatTableReturn; } 

But is there a better way? Penetration through so many times does not feel good

+8
source share
7 answers

The answers above do not address the problem of a dictionary having more than 1 line. This solution fixes the problem.

 static DataTable ToDataTable(List<Dictionary<string, int>> list) { DataTable result = new DataTable(); if (list.Count == 0) return result; var columnNames = list.SelectMany(dict=>dict.Keys).Distinct(); result.Columns.AddRange(columnNames.Select(c=>new DataColumn(c)).ToArray()); foreach (Dictionary<string,int> item in list) { var row = result.NewRow(); foreach (var key in item.Keys) { row[key] = item[key]; } result.Rows.Add(row); } return result; } static void Main(string[] args) { List<Dictionary<string, int>> it = new List<Dictionary<string, int>>(); Dictionary<string, int> dict = new Dictionary<string, int>(); dict.Add("a", 1); dict.Add("b", 2); dict.Add("c", 3); it.Add(dict); dict = new Dictionary<string, int>(); dict.Add("bob", 34); dict.Add("tom", 37); it.Add(dict); dict = new Dictionary<string, int>(); dict.Add("Yip Yip", 8); dict.Add("Yap Yap", 9); it.Add(dict); DataTable table = ToDictionary(it); foreach (DataColumn col in table.Columns) Console.Write("{0}\t", col.ColumnName); Console.WriteLine(); foreach (DataRow row in table.Rows) { foreach (DataColumn column in table.Columns) Console.Write("{0}\t", row[column].ToString()); Console.WriteLine(); } Console.ReadLine(); } 

And the result looks like ...

 abc bob tom Yip Yip Yap Yap 1 2 3 34 37 8 9 
+12
source

Speed, elegance and reuse do not go together. You always choose the more important and try to balance the other two.

Rather, the code is ugly. Satisfied, it is less reusable.

Here is an example of an “elegant” solution, but it is not very readable.

 private static DataTable ToDictionary(List<Dictionary<string, int>> list) { DataTable result = new DataTable(); if (list.Count == 0) return result; result.Columns.AddRange( list.First().Select(r => new DataColumn(r.Key)).ToArray() ); list.ForEach(r => result.Rows.Add(r.Select(c => c.Value).Cast<object>().ToArray())); return result; } 
+6
source

How about something like the code below?

Good, because iterates through each line exactly once. This should be pretty fast, I have included obvious exceptions to make the code more secure.

 private static DataTable DictionariesToDataTable<T>( IEnumerable<IDictionary<string, T>> source) { if (source == null) { return null; } var result = new DataTable(); using (var e = source.GetEnumerator()) { if (!e.MoveNext()) { return result; } if (e.Current.Keys.Length == 0) { throw new InvalidOperationException(); } var length = e.Current.Keys.Length; result.Columns.AddRange( e.Current.Keys.Select(k => new DataColumn(k, typeof(T))).ToArray()); do { if (e.Current.Values.Length != length) { throw new InvalidOperationException(); } result.Rows.Add(e.Current.Values); } while (e.MoveNext()); return result; } } 
+1
source

Try the following:

  private DataTable GetDataTableFromDictionaries<T>(List<Dictionary<string, T>> list) { DataTable dataTable = new DataTable(); if (list == null || !list.Any()) return dataTable; foreach (var column in list.First().Select(c => new DataColumn(c.Key, typeof(T)))) { dataTable.Columns.Add(column); } foreach (var row in list.Select( r => { var dataRow = dataTable.NewRow(); r.ToList().ForEach(c => dataRow.SetField(c.Key, c.Value)); return dataRow; })) { dataTable.Rows.Add(row); } return dataTable; } 
+1
source

try my solution, it seems to me very clean:

 private DataTable DictonarysToDataTable(List<Dictionary<string, int>> list) { DataTable table = new DataTable(); foreach (Dictionary<string,string> dict in list) //for every dictonary in the list .. { foreach (KeyValuePair<string,int> entry in dict) //for every entry in every dict { if (!myTable.Columns.Contains(entry.Key.ToString()))//if it doesn't exist yet { myTable.Columns.Add(entry.Key); //add all it keys as columns to the table } } table.Rows.Add(dict.Values.ToArray()); //add the the Values of every dict in the list as a new row } return table; } 

Edit: About Snap, this only works for one Dictionary. I did not think about that. But maybi you can change it to work in the list of dictionaries ..

0
source

Please try

  DataTable table = new DataTable(); foreach (IDictionary<string, object> row in DeviceTypeReport) { foreach (KeyValuePair<string, object> entry in row) { if (!table.Columns.Contains(entry.Key.ToString())) { table.Columns.Add(entry.Key); } } table.Rows.Add(row.Values.ToArray()); } 
0
source
 private DataTable toDataTable(List<RetirementDiskModelDto> retirementDiskModelDtos) { DataTable result = new DataTable(); foreach (var col in retirementDiskModelDtos.FirstOrDefault().Items) result.Columns.Add(col.Key); foreach (var row in retirementDiskModelDtos) { DataRow newrow = result.NewRow(); foreach (var col in retirementDiskModelDtos.FirstOrDefault().Items) newrow[col.Key] = col.Value; result.Rows.Add(newrow); } return result; } 
0
source

All Articles