Is there a "DataTable" with a "named string" in C #?

I need a data structure with a named column and row. For instance:

magic_data_table: col_foo col_bar row_foo 1 3 row_bar 2 4 

I need to have access to elements like magic_data_table["row_foo", "col_bar"] (which will give me 3 )

I also need to be able to add new columns, for example:

 magic_data_table.Columns.Add("col_new"); magic_data_table["row_foo", "col_new"] = 5; 

AFAIK, DataTable only named column ...

EDIT: I do not need to change the name of the column or row. However, I may need to insert new rows in the middle of the table.

+4
source share
3 answers

While you can use Dictionary<string, Dictionary<string, T>> to do what you want, it would not be particularly memory efficient and could disrupt the synchronization of internal dictionaries. If you create your own data structure, although this is a facade for lists, using dictionaries to map column names to indexes, then this is simple enough:

 public class MyDataStructure<T>//TODO come up with better name { private Dictionary<string, int> columns; private Dictionary<string, int> rows; private List<List<T>> data; public MyDataStructure( IEnumerable<string> rows, IEnumerable<string> columns) { this.columns = columns.Select((name, index) => new { name, index }) .ToDictionary(x => x.name, x => x.index); this.rows = rows.Select((name, index) => new { name, index }) .ToDictionary(x => x.name, x => x.index); initData(); } private void initData() { data = new List<List<T>>(rows.Count); for (int i = 0; i < rows.Count; i++) { data.Add(new List<T>(columns.Count)); for (int j = 0; j < columns.Count; j++) { data[i].Add(default(T)); } } } public T this[string row, string column] { //TODO error checking for invalid row/column values get { return data[rows[row]][columns[column]]; } set { data[rows[row]][columns[column]] = value; } } public void AddColumn(string column) { columns.Add(column, columns.Count); for (int i = 0; i < data.Count; i++) { data[i].Add(default(T)); } } public void AddRow(string row) { rows.Add(row, rows.Count); var list = new List<T>(columns.Count); data.Add(list); for (int i = 0; i < columns.Count; i++) { list.Add(default(T)); } } public bool RenameRow(string oldRow, string newRow) { if (rows.ContainsKey(oldRow) && !rows.ContainsKey(newRow)) { this.Add(newRow, rows[oldRow]); this.Remove(oldRow); return true; } return false; } } 

Note: if you want to fix rows / columns when building, you can use T[,] as the basis for the data, which would make the class much easier to implement, and then reduce the memory overhead, although this does not seem to work for your use cases.

+4
source

Add a column for the name - "name" in the following:

 DataTable table = ... DataColumn nameCol = table.Columns["name"]; var index = table.Rows.Cast<DataRow>() .ToDictionary(row => (string)row[nameCol]); ... // then when you need the values: string rowName = ..., colName = ... var val = index[rowName][colName]; 
+3
source

You may find that the Tuple class (.net 4.0 and above) is suitable for your needs. It will not work strictly like a table, but it will give you more flexibility.

You can use List <> generic to store it and LINQ to query your data.

 List<Tuple<string, string, int>> magicTable = new List<Tuple<string, string, int>>(); magicTable.AddRange(new Tuple<string, string, int>[] { Tuple.Create("row_foo", "col_foo", 1), Tuple.Create("row_foo", "col_bar", 2), Tuple.Create("row_bar", "col_foo", 3), Tuple.Create("row_bar", "col_bar", 4)}); magicTable.Add(Tuple.Create("row_foo", "col_new", 5)); int value = magicTable.Single(tuple => (tuple.Item1 == "row_foo" && tuple.Item2 == "col_new")).Item3; 

It will be quite resource intensive due to duplicate row / column names, but you will get more flexibility for small datasets.

Microsoft Tuple documenation (3-tuple): http://msdn.microsoft.com/en-us/library/dd387150.aspx

0
source

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


All Articles