The DataTable below:
ClassID ClassName StudentID StudentName
1 A 1000 student666
2 B 1100 student111
5 C 1500 student777
1 A 1200 student222
2 B 1080 student999
The dictionary key is composed of "ClassID ,ClassName " and value is composed of "StudentID,StudentName" .
Dictionary<string, string> d = new Dictionary<string, string>();
foreach (DataRow dr in table.Rows)
{
string key=dr["ClassID"].ToString() + dr["ClassName"].ToString();
if (!d.ContainsKey(key))
{
//Do something();......
}
else
{
//Do something();......
}
}
foreach (var s in d.Keys)
{
Response.Write(s+"|+"+d[s]+"<br>");
}
Is there a faster way?
assume that key is '1,A' ,Value should be ' 1000,student666' and '1200,student222'
Here goes then. Using Linq, you can group them then perform string concatenation if you want.
// Start by grouping
var groups = table.AsEnumerable()
.Select(r => new {
ClassID = r.Field<int>("ClassID"),
ClassName = r.Field<string>("ClassName"),
StudentID = r.Field<int>("StudentID"),
StudentName = r.Field<string>("StudentName")
}).GroupBy(e => new { e.ClassID, e.ClassName });
// Then create the strings. The groups will be an IGrouping<TGroup, T> of anonymous objects but
// intellisense will help you with that.
foreach(var line in groups.Select(g => String.Format("{0},{1}|+{2}<br/>",
g.Key.ClassID,
g.Key.ClassName,
String.Join(" and ", g.Select(e => String.Format("{0},{1}", e.StudentID, e.StudentName))))))
{
Response.Write(line);
}
Try this:
Dictionary<string, string> d = new Dictionary<string, string>();
foreach (DataRow dr in table.Rows)
{
string key=dr["ClassID"].ToString() + "-" + dr["ClassName"].ToString();
string value=dr["StudentID"].ToString() + "-" + dr["StudentName"].ToString();
if (!d.ContainsKey(key))
{
d.Add(key, value);
}
}
Reference
Dictionary.Add Method
OR ELSE Try Onkelborg's Answer
How to use compound key for dictionary?
The tricky thing here is the composite key (ClassID, ClassName). Once you identify that, it's easy to search this site for the solution.
I'd recommend using tuples as pointed out here: Composite Key Dictionary
The easiest way is to use a string value of ClassID|ClassName as key. For example, use string value "1|A" for key for the first row, and string value "2|B" for key for the second row, etc.
Here is something that can give you an idea:
using System;
using System.Data;
using System.Collections.Generic;
namespace SO17416111
{
class Class
{
public int Id { get; set; }
public string Name { get; set; }
}
// Note that definition of Class and Student only differ by name
// I'm assuming that Student can/will be expanded latter.
// Otherwise it's possible to use a single class definition
class Student
{
public int Id { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main()
{
DataTable table = GetData();
Dictionary<Class, List<Student>> d = new Dictionary<Class, List<Student>>();
foreach (DataRow dr in table.Rows)
{
// If it's possible to get null data from the DB the appropriate null checks
// should also be performed here
// Also depending on actual data types in your DB the code should be adjusted as appropriate
Class key = new Class {Id = (int) dr["ClassID"], Name = (string) dr["ClassName"]};
Student value = new Student { Id = (int)dr["StudentID"], Name = (string)dr["StudentName"] };
if (!d.ContainsKey(key))
{
d.Add(key, new List<Student>());
}
d[key].Add(value);
}
foreach (var s in d.Keys)
{
foreach (var l in d[s])
{
Console.Write(s.Id + "-" + s.Name + "-" + l.Id + "-" + l.Name + "\n");
}
}
}
// You don't need this just use your datatable whereever you obtain it from
private static DataTable GetData()
{
DataTable table = new DataTable();
table.Columns.Add("ClassID", typeof (int));
table.Columns.Add("ClassName", typeof (string));
table.Columns.Add("StudentID", typeof (int));
table.Columns.Add("StudentName", typeof (string));
table.Rows.Add(1, "A", 1000, "student666");
table.Rows.Add(2, "B", 1100, "student111");
table.Rows.Add(5, "C", 1500, "student777");
table.Rows.Add(1, "A", 1200, "student222");
table.Rows.Add(2, "B", 1080, "student999");
return table;
}
}
}
Note, that this can be compiled and tested as a console application - I substituted your Response.Write with Console.Write. I'm also generating a test DataTable, you should be able to use one that is already present in your application. As far as Class/Student classes go, you have several options here: you can have two separate classes as I show, you can use the same class or you can even use a Tuple class. I suggest you use two separate classes, as it improves readability and maintainability.
Note if you just need to output them, you don't need a dictionary or anything to that effect:
// Add null checks and type conversions as appropriate
foreach (DataRow dr in table.Rows)
{
Response.Write(dr["ClassID"] + "-" + dr["ClassName"] + "-" + dr["StudentID"] + "-" + dr["StudentName"] + "<br>");
}
Related
I have created a Dictionary called 'sGC' that has a string key and a value of a Tuple containing 2 lists of strings.
Dictionary<string, Tuple<List<string>, List<string>>> sGC = new Dictionary<string, Tuple<List<string>, List<string>>>();
I want to add new keys to this dictionary that are concatenated strings from a DataTable DataRow (DR). If a certain criteria is met then a string from the DR goes in either Item1 or Item2 of the Tuple.
This code is being executed in a foreach loop iterating through the DataTable, stopping on certain rows if the row meets an if statement criteria.
var dicTup = new Tuple<List<string>,List<string>>(new List<string>(), new List<string>());
dicTup.Item2.Add(DR["PupilID"].ToString());
sGC.Add(DR["CSN"].ToString() + DR["AW2"].ToString(), dicTup);
Is this the best way to add new dynamically named keys to the dictionary?
I believe the top answer from this JavaScript thread is an answer that I am looking for in C#: How to create dictionary and add key–value pairs dynamically?
Full code below.
foreach (DataRow DR in MainData.DataTable.Rows)
{
//Rows containing a symbol mark score
if ((DR["CN"].ToString() == "LC") && (DR["AW2"].ToString() != ""))
{
//Store male results
//If the Subject Name + Level Code is already a key in the dictionary, append to Tuple List 1
//If key does not exist in Dictionary, create new DictKey and value
if (DR["PG"].ToString() == "Male")
{
if (sGC.ContainsKey(DR["CSN"].ToString() + DR["AW2"].ToString()))
{
sGC[DR["CSN"].ToString() + DR["AW2"].ToString()].Item1.Add(DR["PID"].ToString());
}
else
{
var dicTup = new Tuple<List<string>,List<string>>(new List<string>(), new List<string>());
dicTup.Item1.Add(DR["PID"].ToString());
sGC.Add(DR["CSN"].ToString() + DR["AW2"].ToString(), dicTup);
}
}
//Store female results
//If the Subject Name + Level Code is already a key in the dictionary, append to Tuple List 2
//If key does not exist in Dictionary, create new DictKey and value
if (DR["PG"].ToString() == "Female")
{
if (sGC.ContainsKey(DR["CSN"].ToString() + DR["AW2"].ToString()))
{
sGC[DR["CSN"].ToString() + DR["AW2"].ToString()].Item2.Add(DR["PID"].ToString());
}
else
{
var dicTup = new Tuple<List<string>,List<string>>(new List<string>(), new List<string>());
dicTup.Item2.Add(DR["PupilID"].ToString());
sGC.Add(DR["CSN"].ToString() + DR["AW2"].ToString(), dicTup);
}
}
}
Newly edited and formatted code:
private void storeMarkSheetData()
{
if (MainData.DataTable != null)
{
if(subjectGradeCounts.Count == 0)
{
foreach (DataRow DR in MainData.DataTable.Rows)
{
string cN = DR["ColumnName"].ToString();
string aW2 = DR["AssessmentAwarded2"].ToString();
string cSN = DR["ClassSubjectName"].ToString();
string pID = DR["PupilID"].ToString();
string pG = DR["PupilGender"].ToString();
//Rows containing a symbol mark score
if ((cN == "Level Code") && (aW2 != ""))
{
//Check to see if the dictionary contains the key, adds it if not
if(!subjectGradeCounts.ContainsKey(cSN + aW2))
{
subjectGradeCounts.Add(cSN+aW2, new
Tuple<List<string>, List<string>>(new List<string>(), new
List<string>()));
}
//Now that the key exists, if it didn't previously
//If male add to list 1, else list 2 (for female)
if(pG == "Male")
{
subjectGradeCounts[cSN + aW2].Item1.Add(pID);
}
else
{
subjectGradeCounts[cSN + aW2].Item2.Add(pID);
}
}
}
}
}
}
Thank you all.
Here I simplified what you have to just check if the key exists, if not it adds it with new initialized lists, then does one if else for if male add to list 1 else (female) add to list 2, from the code you posted this is what I came up with
foreach (DataRow DR in MainData.DataTable.Rows)
{
//Rows containing a symbol mark score
if ((DR["CN"].ToString() == "LC") && (DR["AW2"].ToString() != ""))
{
//Check to see if your dictionary contains the key, if not, add it
if(!sGC.ContainsKey(DR["CSN"].ToString() + DR["AW2"].ToString()))
{
sGC.Add(DR["CSN"].ToString() + DR["AW2"].ToString(), new
Tuple<List<string>,List<string>>(new List<string>(), new
List<string>()));
}
//Now that the key exists, if it didn't previously
//If male add to list 1, else list 2 (for female)
if(DR["PG"].ToString() == "Male")
{
sGC[DR["CSN"].ToString() + DR["AW2"].ToString()].Item1.Add(DR["PupilID"].ToString());
}
else
{
sGC[DR["CSN"].ToString() + DR["AW2"].ToString()].Item2.Add(DR["PupilID"].ToString());
}
}
}
I have a web service and in the code below I loop through a collection of items. These items are desplayed in an xml like fashion (see example below). However I would like to display them in table like fashion. I thought of using the datatable to insert the items in there and then redisplay them.
585344
585344 Title Issue 1
585344 Number 140024
585344 State In progress
585350
585350 Title Issue 2
585350 Number 140026
585350 State Classification
How can I display them like this:
ID | Title | Number | State
585344 issue 1 140024 In progress
static void Main(string[] args)
{
ABWebService webSvc = new ABWebService();
GetObjectListData gold = new GetObjectListData();
gold.folderPath = "01. ITSM - Service Operation";
gold.RequiredField = new RequiredField[3];
gold.RequiredField[0] = new RequiredField {Value = "Title"};
gold.RequiredField[1] = new RequiredField {Value = "Number"};
gold.RequiredField[2] = new RequiredField {Value = "State"};
try
{
GetObjectListResult golr = webSvc.GetObjectList(gold);
List<NewsTracker> list = new List<NewsTracker>();
if (golr.success)
{
ObjectData[] myObjects = golr.Object;
for (int i = 0; i < myObjects.Length; i++)
{
Console.WriteLine(myObjects[i].id);
foreach (object myItem in myObjects[i].Items)
{
string field1 = string.Empty;
string val1 = string.Empty;
int val2 = 0;
string field2 = string.Empty;
StringVal item = myItem as StringVal;
if (item != null)
{
field1 = item.name;
val1 = item.Value;
Console.WriteLine("\t" + myObjects[i].id + " " + field1 + " " + val1);
}
LongIntVal val = myItem as LongIntVal;
if (val != null)
{
field2 = val.name;
val2 = val.Value;
Console.WriteLine("\t" + myObjects[i].id + " " + field2 + " " + val2);
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
EDIT 1:
can you tell me how can I add them in a generic list like this: list.Add(new NewsTracker(title,number,state)); so that I can loop through and do other things with the list?
if you have only simple types then you can use reflection instead to build that table. here an example of a method i often use to send class info to a web service. Can be tweaked to receive a List and create 1 table with multiple rows once you understand the logic
public static DataTable ObjectToData(object o)
{
DataTable dt = new DataTable("OutputData");
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
o.GetType().GetProperties().ToList().ForEach(f =>
{
try
{
f.GetValue(o, null);
dt.Columns.Add(f.Name, f.PropertyType);
dt.Rows[0][f.Name] = f.GetValue(o, null);
}
catch { }
});
return dt;
}
If you pass the object ClassA per structure below
ClassA
{
string Value1 = "abc";
DateTime Value2 = DateTime.Now();
int Value3 = 12;
}
ObjectToData(MyClassA); datatable will look like the following :
|----------|-------------------------|----------|
| Value1 | Value2 | Value3 |
|==========|=========================|==========|
| "abc" | 2015/10/30 08:00:00 AM | 12 |
|----------|-------------------------|----------|
You could group by the key (ID in your example) and fill the other values accordingly. If you want a generic code, you could use some generic properties, correlating "name of column" and "value", like this:
Pseudo-code:
// Consider ID as the key (maybe int in your case) and GenericProperty as a class of just 2 properties: name of property and value.
List<YourClass> list;
Dictionary<ID, HashSet<GenericProperty>> dict = ConvertToDictionary(list); // Convert the list to a dictionary
// Aggregate values per ID (key)
// You can get the PropertyName with reflection
foreach (var pair in dict)
{
var row = DataTable.Rows.AddRow();
foreach (var values in pair.Value)
row[pair.Value.PropertyName] = pair.Value.Value;
}
Note that if you don't need a generic code, than the class GenericProperty could be an specific class with all values as properties. In your example, 3 properties: title, number, state. Then you can use them to fill the DataTable. Example as follow:
Aditionally, you can get the property name and value with reflection (example here), or as Franck said.
EDIT (based on questions edit):
Let's make an example for "myObjects" object that you've shown.
If I understood correctly, "myObjects" is already your grouped list. So "myObjects.Items" are the values of one grouped key.
So we have:
List<NewsTracker> list = new List<NewsTracker>(myObjects.Count);
foreach (var obj in myObjects)
{
// 'obj' is one key, so one value of NewsTracker
NewsTracker nt = new NewsTracker();
foreach (var item in myObjects.Items)
{
// Capture the name of the item and check what property is it from
// Code you've show in your question. --> I'll consider that you already know how to get "fieldName" as with "value" (object)
if (fieldName.Equals("Title"))
nt.Title = (string)value;
else if (fieldName.Equals("Number")
nt.Number = (int)value;
// ... and so on ...
}
// At the end of the inner loop, we must have a "NewsTracker" filled with the correct values, so now we only need to add them to the main list
list.Add(nt);
}
Note: I've wrote an specific code to your problem considerind the 'NewsTracker' class.
I'm creating Datatables from .csv files. This part actually works. My current issue is the following one:
I have to compare two or more Datatable's with the same structure. So
Datatable1:
KeyColumn, ValueColumn
KeyA, ValueA
KeyB, ValueB
KeyC, ValueC
Datatable2:
KeyColumn, ValueColumn
KeyB, ValueB
KeyC, ValueC
KeyD, ValueD
And this should end up like this:
ResultDatatable:
KeyColumn, ValueColumn (of DT1), ValueColumn (of DT2)
KeyA, ValueA
KeyB, ValueB (of DT1), ValueB (of DT2)
KeyC, ValueC (of DT1), ValueC (of DT2)
KeyD, ValueD
I can't even manage to insert the Data of the first Datatable because of different ColumnNames. Another problem is, that the Datatables own the same ColumnNames, so I can't add those to the ResultDatatable.
I have tried many ways and end up with no solution. Any ideas how to address this problem?
Edit:
The solution with Dictionaries was too sophisticated, so I continued trying to solve it with the Datatables. The source of the problem was something very unexpected.
The attempt to rename a column name to something, which contains a simple dot ('.') results with losing all data in that column.
e.g. If you have Datatable dt:
PrimaryColumn, ValueColumn
KeyA1, KeyB1
KeyA2, KeyB2
After dt.Columns[ValueColumn].ColumnName = "Value.Column"; You will lose any data in that column. I will ask MS, if this is desired or if it is a Bug in the .NET-Framework. Here is my final Code (C#). I have List<string>keys which will remain in the resultTable. and List<string>values which will be added for every Table that should be compared.
private DataTable CompareTables(List<AnalyseFile> files, Query query, List<string> keys, List<string> values) {
// Add first table completely to resultTable
DataTable resultTable =
files[0].GetDataTable(false, query.Header, query.Startstring, query.Endstring, query.Key).Copy();
foreach (string value in values) {
resultTable.Columns[value].ColumnName = "(" + files[0].getFileNameWithoutExtension() + ") " + value;
}
// Set primary keys
resultTable.PrimaryKey = keys.Select(key => resultTable.Columns[key]).ToArray();
// process remaining tables
for (int i = 1; i < files.Count; i++) {
DataTable currentTable = files[i].GetDataTable(false, query.Header, query.Startstring, query.Endstring, query.Key);
// Add value-columns to the resultTable
foreach (string value in values) {
resultTable.Columns.Add("(" + files[i].getFileNameWithoutExtension() + ") " + value);
}
// Set again primary keys
currentTable.PrimaryKey = keys.Select(key => currentTable.Columns[key]).ToArray();
// populate common Rows
foreach (DataRow dataRow in resultTable.Rows) {
foreach (DataRow row in currentTable.Rows) {
foreach (string key in keys) {
if (dataRow[key].ToString().Equals(row[key].ToString())) {
foreach (string value in values) {
string colname = "(" + files[i].getFileNameWithoutExtension() + ") " + value;
dataRow[colname] = row[value];
}
}
}
}
}
// Get all Rows, which do not exist in resultTable yet
IEnumerable<string> isNotinDT =
currentTable.AsEnumerable()
.Select(row => row.Field<string>(keys[0]))
.Except(resultTable.AsEnumerable().Select(row => row.Field<string>(keys[0])));
// Add all the non existing rows to resulTable
foreach (string row in isNotinDT) {
DataRow currentRow = currentTable.Rows.Find(row);
DataRow dRow = resultTable.NewRow();
foreach (string key in keys) {
dRow[key] = currentRow[key];
}
foreach (string value in values) {
dRow["(" + files[i].getFileNameWithoutExtension() + ") " + value] = currentRow[value];
}
resultTable.Rows.Add(dRow);
}
}
return resultTable;
}
Any improvements are Welcome!
Ok Here is an example of my version using the dictionaries.
Fiddle: http://dotnetfiddle.net/AljK9J
//Setup Sample Data
var data1 = new Dictionary<string, string>();
data1.Add("KeyA", "ValueA");
data1.Add("KeyB", "ValueB");
data1.Add("KeyC", "ValueC");
var data2 = new Dictionary<string, string>();
data2.Add("KeyB", "ValueB");
data2.Add("KeyC", "ValueC");
data2.Add("KeyD", "ValueD");
//Second DataType in the Dictionary could be something other than a Tuple
var result = new Dictionary<string, Tuple<string, string>>();
//Fill in for items existing only in data1 and in both data1 and data2
foreach(var item in data1)
{
result.Add(item.Key, new Tuple<string, string>(item.Value, data2.FirstOrDefault(x => x.Key == item.Key).Value));
}
//Fill in remaining items that exist only in data2
foreach(var item in data2.Where(d2 => !result.Any(x => x.Key == d2.Key )))
{
result.Add(item.Key, new Tuple<string, string>(null, item.Value));
}
//Demonstrating how to access the data
var formattedOutput = result.Select(x => string.Format("{0}, {1} (of D1), {2} (of D2)", x.Key, x.Value.Item1 ?? "NoValue", x.Value.Item2 ?? "NoValue"));
foreach(var line in formattedOutput)
{
Console.WriteLine(line);
}
is it possible to create a value range constraint on a DataTable in C#?
I'm dynamically adding a column to a DataTable:
this.PrimaryCorrelationMatrix.Columns.Add(sName, typeof(int));
but I'd like all values within this Column to be integers from [0, 10]. Can I implement such a constraint directly on the DataTable?
The next best option I can think of is to create some object with possible values [0, 10], and instead of typeof(int), using typeof(specialObj).
One way to do this is to inspect the e.ProposedValue in the ColumnChanging event of the DataTable.
To have the constraint on a particular column, you can use the ExtendedProperties collection of the DataColumn to act as your flag to check those constraints:
DataTable dt = new DataTable();
DataColumn dc = new DataColumn("Range", typeof(int));
dc.ExtendedProperties.Add("Min", 0);
dc.ExtendedProperties.Add("Max", 10);
dt.Columns.Add(dc);
dt.ColumnChanging += dt_ColumnChanging;
In the ColumnChanging event, you would check if those properties exist, then use them:
void dt_ColumnChanging(object sender, DataColumnChangeEventArgs e) {
if (e.Column.ExtendedProperties.ContainsKey("Min") &&
e.Column.ExtendedProperties.ContainsKey("Max")) {
int min = (int)e.Column.ExtendedProperties["Min"];
int max = (int)e.Column.ExtendedProperties["Max"];
if ((int)e.ProposedValue < min) e.ProposedValue = min;
if ((int)e.ProposedValue > max) e.ProposedValue = max;
}
}
I can recommend you to forget about data tables and use classes. You can use data annotation to validate your model.
Use this attribute to validate a range of values for an specific property/
This code is extracted from the specified article(example of class making the validation of a range):
public class Product
{
[Range(5, 50)]
public int ReorderLevel { get; set; }
[Range(typeof(Decimal),"5", "5000")]
public decimal ListPrice { get; set; }
}
Your are going to find a lot of benefits of using classes.
This is an old post but I am using a solution to sync the Check_Constraints NOT filled by the OleDbDataAdapter.FillSchema on Access Databases worth to mention. Just used a OleDbConnection to retrieve GetOleDbSchemaTable and foreach() the rows extracting the validation text expression and created an anonymous delegate at the appropriate Table & Column attached to the proper Table.ColumnChanging event. The string validation provided by the Access schema will then be evaluated dynamically by the handy Eval() function described here. There is my code:
DataTable schemaTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Check_Constraints, null);
// Attach delegate Eval() of each Check_Constraints on proper Table/Column
foreach (DataRow myField in schemaTable.Rows)
{
string constraint_name = "";
string check_clause = "";
foreach (DataColumn myProperty in schemaTable.Columns)
{
if (myProperty.ColumnName == "CONSTRAINT_NAME")
constraint_name = myField[myProperty.ColumnName].ToString();
if (myProperty.ColumnName == "CHECK_CLAUSE")
check_clause = myField[myProperty.ColumnName].ToString();
}
var rule = constraint_name.Replace("[", "").Replace("]", "").Split('.');
if (rule.Length == 3 && dataset.Tables.Contains(rule[0]) && dataset.Tables[rule[0]].Columns.Contains(rule[1]) && String.IsNullOrEmpty(check_clause) == false)
{
dataset.Tables[rule[0]].ColumnChanging += delegate (object sender, DataColumnChangeEventArgs e)
{
if (e.Column.ColumnName == rule[1] && Convert.ToBoolean(ToolBox.Eval(e.ProposedValue + check_clause)) == false)
{
throw new Exception("Tabela: " + rule[0] + ", coluna: " + rule[0] + ", cheque: " + check_clause);
}
};
Debug.WriteLine(rule[0] + "." + rule[1] + ": " + check_clause);
}
}
I have fallen into a doubt and I don't know how to solve it, the case is:
I have created an "arrayed string" list like this:
List<string[]> definitions;
I have added to it values like this:
definitions.Add(new string[2] { "A", "Def.1" });
definitions.Add(new string[2] { "B", "Def.2" });
In order to show the values I do it like this:
foreach (string[] theDefinition in definitions)
{
Console.WriteLine(theDefinition[0] + "\tdef: " + theDefinition[1]);
}
So far this works fine, but how can I show the values without the foreach I mean something like this:
Console.WriteLine(definitions[0] ...)
What should I write in the 3 dots to show either the "A" or the "Def.1" from the list in index 0.
I guess overcoming this is by doing something like:
string[] temp = definitions[0]
Console.WriteLine(temp[0] + ", " + temp[1]);
How to achieve it just using the Console.WriteLine without using extra variables, is this possible? and how? Thank you in advance.
Console.WriteLine(definitions[0][0] + "\tdef: " + definitions[0][1]);
The other answers are correct of course but why not just use a Dictionary instead of List of a 2 dimensional string array.
var definitions = new Dictionary<string, string>
{
{ "A", "Def.1" },
{ "B", "Def.2" }
};
foreach (var keypair in definitions)
{
Console.WriteLine("{0} \tdef: {1} ", keypair.Key, keypair.Value);
}
A better way would be to declare a definition type
public class Definition
{
public string Name { get; set; }
public string Value { get; set; }
public override string ToString()
{
return Name + "\tdef: " + Value;
}
}
Now you can simplify your code like this
List<Definition> definitions = new List<Definition> {
new Definition { Name = "A", Value = "Def.1" },
new Definition { Name = "B", Value = "Def.2" },
};
foreach (Definition theDefinition in definitions)
{
Console.WriteLine(theDefinition);
}
Of cause you can use a fluent version of it as proposed by Nikhil Agrawal, which is now even simpler.
definitions.ForEach(def => Console.WriteLine(def));
prints
A def: Def.1
B def: Def.2
And accessing the fields is more descriptive than using array indexes
Definition def = definitions[0];
Console.WriteLine(def.Name + ", " + def.Value);
// compared to
// Console.WriteLine(temp[0] + ", " + temp[1]);
You can access it like this: definitions[definition_index][string_index].
Try:
Console.WriteLine(definitions[0][0] + "\tdef: " + definitions[0][1]);
for (var i = 0; i < definitions.Length; i++)
{
Console.WriteLine(definitions[i][0] + "\tdef: " + definitions[i][1]);
}
One Line Answer instead of 3 Lines. No use of For or foreach Loop or Extra Variable when LINQ is here
definitions.ForEach(x => Console.WriteLine(x[0] + "\tdef: " + x[1]));