I've got a dictionary laid out like so:
Dictionary<string, List<Series>> example = new Dictionary<string, List<Series>>();
example.Add("Meter1",new List<Series>(){ new Series{ name="Usage", data = new double[] {1,2,3}},
new Series{ name = "Demand", data= new double[]{4,5,6}}});
example.Add("Meter2", new List<Series>(){ new Series{ name="Usage", data = new double[] {1,2,3}},
new Series{ name = "Demand", data= new double[]{4,5,6}}});
What I need is:
Dictionary<string, List<Series>> exampleResult = new Dictionary<string, List<Series>>();
exampleResult.Add("Usage", new List<Series>(){ new Series{ name="Meter1", data = new double[] {1,2,3}},
new Series{ name = "Meter2", data= new double[]{1,2,3}}});
exampleResult.Add("Demand", new List<Series>(){ new Series{ name="Meter1", data = new double[] {4,5,6}},
new Series{ name = "Meter2", data= new double[]{4,5,6}}});
That is, the dictionary projected "sideways", with the name of each Series as the key in the new dictionary, with the key of the old dictionary used as the name of the series.
Here's the series class...
public class Series
{
public string name { get; set; }
public double[] data { get; set; }
}
Sorry if I am not expressing this problem clearly, please ask any questions you'd like, and thanks in advance for any help...
EDITED TO ADD EXAMPLE
Create a grouping and then select out the new keys and values to create a dictionary. Like this:
// source data
var d = new Dictionary<string, Series[]>
{
{
"key1", new[]
{
new Series
{
name = "Usage",
data = new double[] {1, 2, 3}
},
new Series
{
name = "Demand",
data = new double[] {4, 5, 6}
}
}
},
{
"key2", new[]
{
new Series
{
name = "Usage",
data = new double[] {1, 2, 3}
},
new Series
{
name = "Demand",
data = new double[] {4, 5, 6}
}
}
}
};
// transform
var y = (
from outer in d
from s in outer.Value
let n = new
{
Key = s.name,
Series = new Series
{
name = outer.Key,
data = s.data
}
}
group n by n.Key
into g
select g
).ToDictionary(g1 => g1.Key,
g2 => g2.Select(g3 => g3.Series).ToArray());
/* results:
var y = new Dictionary<string, Series[]>
{
{
"Usage",
new[]
{
new Series
{
name = "key1",
data = new double[] { 1, 2, 3 }
},
new Series
{
name = "key2",
data = new double[] { 1, 2, 3 }
}
}
},
{
"Demand",
new[]
{
new Series
{
name = "key1",
data = new double[] {4, 5, 6},
},
new Series
{
name = "key2",
data = new double[] {4, 5, 6}
}
}
}
};
*/
Try this:
example
.SelectMany(x => x.Value
.Select(y => y.name)
).Distinct()
.ToDictionary(
x => x,
x => example
.SelectMany(y => y.Value
.Where(z => z.name == x)
.Select(z => new Series{ name = y.Key, data = z.data })
).ToList()
)
Related
I am trying to get into more complex Linq queries and right away catch a point I am feeling stuck. I have a following list in DB:
ID ELAPSED TIME APPISRUNNING
1 12 TRUE
2 54 TRUE
3 32 FALSE
Where ELAPSED TIME is TimeSpan and APPISRUNNING is a bool.
I would like to build a chart based on these values (https://github.com/beto-rodriguez/LiveCharts2). Chart build fine with this:
Title = "Analytics";
this.ActivityChartSeries = new ISeries[]
{
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
new PieSeries<double> { Values = new double[] { 2 }},
};
Now I somehow need to first GroupBy bool and then select a new List? I have tried following:
IEnumerable<DataRecord> dataRecords = await this.DataStore.GetItemsAsync();
this.ActivityChartSeries = dataRecords
.GroupBy(g => g.AppIsRunning)
.Select(m => new
{ // BELOW IS TOTALLY UNCLEAR FOR ME
Values = m.Select(r => r.EngineElapsed.Ticks),
Name = m.Select(r => r.Name),
})
.Select(x =>
new PieSeries<double>
{
Values = new List<double> { x.Values.FirstOrDefault() },
Name = x.Name.FirstOrDefault(),
});
Type of assigned variable:
public IEnumerable<ISeries> ActivityChartSeries
This part is totally unclear for me:
Values = m.Select(r => r.EngineElapsed.Ticks),
Name = m.Select(r => r.Name),
How after GroupBy I can create two types of data? Basically I need
"Application Running" and "Values"
"Application is not Running" and "Values"
EDIT:
Code provided by Somar Zein compiles fine:
var results = activityChartSeries
.GroupBy(a=> a.AppIsRunning)
.Select(item=> new PieSeries<double>{
Name = item.Key ? "Application is Running" : "Application is not Running",
Values = item.Select(x=> Convert.ToDouble(x.ElapsedTime.Ticks)).ToList()
});
However as a result I am getting something like this, why it is reloading in a loop?
Here is result:
enter image description here
EDIT2:
So I have created an example for testing purposes:
Class:
public class DataModel
{
public int Id { get; set; }
public TimeSpan ElapsedTime { get; set; }
public bool AppIsRunning { get; set; }
}
Code:
List<DataModel> records = new List<DataModel>();
records.Add(new DataModel { Id = 1, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 2, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 3, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 4, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
records.Add(new DataModel { Id = 5, ElapsedTime = new TimeSpan(1, 20, 30), AppIsRunning = true });
this.ActivityChartSeries = records
.GroupBy(g => g.AppIsRunning)
.Select(item => new PieSeries<double>
{
Name = item.Key ? "Running" : "Not Running",
Values = new double[] { 2, 4 },
});
I get the same reloading effect, even thou originally provided Example from LiveCharts work fine.
you could try doing something like following:
var results = activityChartSeries
.GroupBy(a=> a.AppIsRunning)
.Select(item=> new PieSeries<double>{
Name = item.Key ? "Application is Running" : "Application is not Running",
Values = item.Select(x=> Convert.ToDouble(x.ElapsedTime.Ticks)).ToList()
});
hope that could be helpful!
I've a List of custom objects called Product: List
class Product
{
string Key1 {get; set;}
string Key2 {get; set;}
int Count1 {get; set;}
int Count2 {get; set;}
}
I'm combining multiple Product lists and I need to create a new list which will have sum values for each of the Count properties.
For e.g.
List 1:
"Key1", "Key2", 1, 2
"Key2", "Key3", 3, 4
List 2:
"Key1", "Key2", 5, 6
"Key2", "Key3", 7, 8
So my new List should be:
New List:
"Key1", "Key2", 6, 8
"Key2", "Key3", 10, 12
Can someone help me on this please?
Thanks.
You can do this
var list1 = new List<Product>()
{
new Product(){Key1 = "Key1", Key2 ="Key2", Count1 = 1, Count2 = 2},
new Product(){Key1 = "Key2", Key2 ="Key3", Count1 = 1, Count2 = 2}
};
var list2 = new List<Product>()
{
new Product(){Key1 = "Key1", Key2 ="Key2", Count1 = 6, Count2 = 8},
new Product(){Key1 = "Key2", Key2 ="Key3", Count1 = 10, Count2 = 12}
};
var result = list1.Concat(list2)
.GroupBy(x => new {x.Key1,x.Key2})
.Select(x => new
{
x.Key.Key1,
x.Key.Key2,
SumCount1 = x.Sum(y => y.Count1),
SumCount2 = x.Sum(y => y.Count2)
}).ToList();
Output
Demo Here
Key1, Key2, 7, 10
Key2, Key3, 11, 14
Additional Resources
List.AddRange
Adds the elements of the specified collection to the end of the
List.
Enumerable.GroupBy Method (IEnumerable, Func, Func)
Groups the elements of a sequence according to a specified key
selector function and projects the elements for each group by using a
specified function.
Enumerable.Concat Method (IEnumerable, IEnumerable)
Concatenates two sequences.
List<Product> lst1 = new List<Product>();
List<Product> lst2 = new List<Product>();
lst1.Add(new Product() {Key1 = "K1",Key2 ="K2", Count1 =1, Count2=2 });
lst1.Add(new Product() { Key1 = "K2", Key2 = "K3", Count1 = 3, Count2 = 4 });
lst2.Add(new Product() { Key1 = "K1", Key2 = "K2", Count1 = 5, Count2 = 6});
lst2.Add(new Product() { Key1 = "K2", Key2 = "K3", Count1 = 7, Count2 = 8 });
// Way 1
var l = lst1.Join(lst2, l1 => l1.Key1, l2 => l2.Key1,
(lt1, lt2) => new Product { Key1 = lt1.Key1, Key2 = lt1.Key2, Count1 = lt1.Count1 + lt2.Count1, Count2 = lt1.Count2 + lt2.Count2 } ).ToList() ;
// Way 2
var result = lst1.Join(lst2, x => new { x.Key1, x.Key2 },
y => new { y.Key1, y.Key2 }, (x, y) =>
new Product { Key1 = x.Key1, Key2 = x.Key2, Count1 = x.Count1 + y.Count1, Count2 = x.Count2 + y.Count2 }).ToList();
I have these lists:
var subjects = new List<SubjectModel>
{
new SubjectModel { subjId = 1, subjName = "Math" },
new SubjectModel { subjId = 2, subjName = "Science" },
new SubjectModel { subjId = 3, subjName = "History" },
new SubjectModel { subjId = 4, subjName = "Language" }
};
var quizzes = new List<QuizModel>
{
new QuizModel { quizId = 1, quizDate = DateTime.Parse("2016-11-25"), quizScore = 10, subjectId = 1 },
new QuizModel { quizId = 2, quizDate = DateTime.Parse("2016-11-25"), quizScore = 15, subjectId = 1 },
new QuizModel { quizId = 3, quizDate = DateTime.Parse("2016-11-25"), quizScore = 8, subjectId = 2 },
new QuizModel { quizId = 4, quizDate = DateTime.Parse("2016-11-26"), quizScore = 13, subjectId = 1 },
new QuizModel { quizId = 5, quizDate = DateTime.Parse("2016-11-26"), quizScore = 20, subjectId = 2 }
};
var exams = new List<ExamModel>
{
new ExamModel { examId = 1, examDate = DateTime.Parse("2016-11-25"), examScore = 90, subjectId = 1 },
new ExamModel { examId = 2, examDate = DateTime.Parse("2016-11-25"), examScore = 88, subjectId = 2 },
new ExamModel { examId = 3, examDate = DateTime.Parse("2016-11-25"), examScore = 92, subjectId = 4 },
new ExamModel { examId = , examDate = DateTime.Parse("2016-11-26"), examScore = 84, subjectId = 1 },
};
var exercises = new List<ExerciseModel>
{
new ExerciseModel { exerciseId = 1, exerciseDate = DateTime.Parse("2016-11-25"), exerciseScore = 17, subjectId = 1 },
new ExerciseModel { exerciseId = 2, exerciseDate = DateTime.Parse("2016-11-25"), exerciseScore = 15, subjectId = 2 },
new ExerciseModel { exerciseId = 3, exerciseDate = DateTime.Parse("2016-11-26"), exerciseScore = 15, subjectId = 1 },
new ExerciseModel { exerciseId = 4, exerciseDate = DateTime.Parse("2016-11-26"), exerciseScore = 12, subjectId = 4 },
new ExerciseModel { exerciseId = 5, exerciseDate = DateTime.Parse("2016-11-26"), exerciseScore = 10, subjectId = 1 },
};
I was able to successfully group each of them by date and by subject.
var allQuizzes = quizzes.GroupBy(qz => qz.quizDate, (q, values) =>
new
{
Date = q,
Quizzes = values.GroupBy(v => v.subjectId, (c, values2) =>
new {
SubjectId = c,
QuizSum = values2.Sum(v2 => v2.quizScore)
})
});
var allExercises = exercises.GroupBy(ex => ex.exerciseDate, (e, values) =>
new {
Date = e,
Exercises = values.GroupBy(x => x.subjectId, (z, values2) =>
new {
SubjectId = z,
ExerSum = values2.Sum(r => r.exerciseScore)
})
});
var allExams = exams.GroupBy(ex => ex.examDate, (e, values) =>
new
{
Date = e,
Exercises = values.GroupBy(x => x.subjectId, (z, values2) =>
new
{
SubjectId = z,
ExamSum = values2.Sum(r => r.examScore)
})
});
However, I need to join all three of them to get the sum of all scores. The final table should display like this.
-----------------------------------------------------------------
| Date | Math | Science | History | Language |
| 11/25/2016 | 132 | 111 | 0 | 92 |
| 11/26/2016 | 122 | 20 | 0 | 12 |
-----------------------------------------------------------------
I tried to join them, but it can't seem to join by multiple columns.
I select from all 3 collections results in form of the same anonymous class (the same Idea had Andrei in first answer), that allows me just to collect all results together in all list, without mapping and converting.
var allQuiz = quizzes.GroupBy(x => new { x.subjectId, x.quizDate })
.Select(x => new {
Date = x.Key.quizDate,
Subj = x.Key.subjectId,
Sum = x.Sum(r=>r.quizScore)});
var allExam= exams.GroupBy(x => new { x.subjectId, x.examDate })
.Select(x => new {
Date = x.Key.examDate,
Subj = x.Key.subjectId,
Sum = x.Sum(r=>r.examScore)});
var allExc = exercises.GroupBy(x => new { x.subjectId, x.exerciseDate })
.Select(x => new {
Date = x.Key.exerciseDate,
Subj = x.Key.subjectId,
Sum = x.Sum(r=>r.exerciseScore)});
Combining of all results together:
var all = allQuiz.ToList();
all.AddRange(allExam.ToList());
all.AddRange(allExc.ToList());
var result = all.GroupBy(x => new { x.Date, x.Subj })
.Select(x => new { x.Key.Date, x.Key.Subj, Sum = x.Sum(s => s.Sum)});
var list = result.GroupBy(r => r.Date).Select(x => new {
Date = x.Key,
Math = x.SingleOrDefault(t=>t.Subj==1)?.Sum ?? 0,
Science = x.SingleOrDefault(t=>t.Subj==2)?.Sum ?? 0,
History = x.SingleOrDefault(t=>t.Subj==3)?.Sum ?? 0,
Language = x.SingleOrDefault(t=>t.Subj==4)?.Sum ?? 0,
});
Output in LinqPad:
Here is an idea. Instead of keeping the distinction while grouping, you could convert all three to the same structure. For instance:
var allQuizzes = quizzes.GroupBy(qz => qz.quizDate, (q, values) =>
new
{
Date = q,
Results = values.GroupBy(v => v.subjectId, (c, values2) =>
new {
SubjectId = c,
Sum = values2.Sum(v2 => v2.quizScore)
})
});
Notice names "Results" and "Sum" - you can use the same for the other two objects. And now you have three collections, all of the same structure:
{
Date:
Results: [
{SubjectId, Sum}
{SubjectId, Sum}
...
]
}
Since they are all the same now, you can stop treating them differently, use UNION to merge all three, group them by date and within that by subject. Then you could probably iterate through subject list to get necessary info, depends on what you mean by "final table".
This is what i came up with.
It may not be best optimized, but might be enough for you.
I rendered the results into a StringBuilder in my test.
var result =
quizzes.Select(q => new {SubjectId = q.subjectId, Date = q.quizDate, Score = q.quizScore})
.Union(exams.Select(e => new {SubjectId = e.subjectId, Date = e.examDate, Score = e.examScore}))
.Union(exercises.Select(e => new {SubjectId = e.subjectId, Date = e.exerciseDate, Score = e.exerciseScore}))
.GroupBy(arg => arg.Date,
(key, values)=>
new
{
Key = key,
Scores = values.GroupBy(v => v.SubjectId, (s, values2) => new { SubjectId = s, SumScore = values2.Sum(v2 => v2.Score) })
});
StringBuilder sb = new StringBuilder("Date\t\t");
foreach (SubjectModel subject in subjects)
{
sb.Append($"{subject.subjName}\t");
}
sb.AppendLine();
foreach (var record in result)
{
sb.Append($"{record.Key.ToShortDateString()}\t");
foreach (SubjectModel subject in subjects)
{
int sum = record.Scores.Where(s => s.SubjectId == subject.subjId).Select(s => s.SumScore).DefaultIfEmpty(0).Single();
sb.Append($"{sum}\t");
}
sb.AppendLine();
}
string finalTable = sb.ToString();
Instead of using three different anonymous objects to hold the results, make your own class:
public enum TestType
{
Quiz,
Exam,
Exercise,
}
public class TestScore
{
public TestType Type { get; set; }
public DateTime Date { get; set; }
public int Score { get; set; }
public int SubjectId { get; set; }
// Constructors - make a TestScore object
public TestScore(QuizModel q)
{
Type = TestType.Quiz;
Date = q.quizDate;
Score = q.quizScore;
SubjectId = q.SubjectId;
}
public TestScore(ExamModel e)
{
Type = TestType.Exam;
Date = e.examDate;
Score = e.examScore;
SubjectId = e.SubjectId;
}
public TestScore(ExerciseModel e)
{
Type = TestType.Exercise;
Date = e.exerciseDate;
Score = e.exerciseScore;
SubjectId = e.SubjectId;
}
}
Convert to TestScore:
List<TestScore> scores = new List<TestScore>();
scores.AddRange(quizzes.Select(q => new TestScore(q));
scores.AddRange(exams.Select(e => new TestScore(e));
scores.AddRange(exercises.Select(e => new TestScore(e));
Now you have one datasource instead of three, displaying the results becomes easy.
I have a class like this:
class item
{
public int Id { get; set; }
public Dictionary<string, int> Data { get; set; }
}
and i have 2 list contain that class object like this :
item obj1 = new item();
obj1.Id = 1;
obj1.Data = new Dictionary<string, int>();
obj1.Data.Add("1", 11);
obj1.Data.Add("2", 12);
obj1.Data.Add("3", 13);
item obj2 = new item();
obj2.Id = 2;
obj2.Data = new Dictionary<string, int>();
obj2.Data.Add("1", 21);
obj2.Data.Add("2", 22);
obj2.Data.Add("3", 23);
item obj3 = new item();
obj3.Id = 3;
obj3.Data = new Dictionary<string, int>();
obj3.Data.Add("1", 31);
obj3.Data.Add("2", 32);
obj3.Data.Add("3", 33);
item obj4 = new item();
obj4.Id = 1;
obj4.Data = new Dictionary<string, int>();
obj4.Data.Add("1", 41);
obj4.Data.Add("2", 42);
obj4.Data.Add("3", 43);
item obj5 = new item();
obj5.Id = 2;
obj5.Data = new Dictionary<string, int>();
obj5.Data.Add("1", 51);
obj5.Data.Add("2", 52);
obj5.Data.Add("3", 53);
item obj6 = new item();
obj6.Id = 3;
obj6.Data = new Dictionary<string, int>();
obj6.Data.Add("1", 61);
obj6.Data.Add("2", 62);
obj6.Data.Add("3", 63);
List<item> lst1 = new List<item>();
lst1.Add(obj1);
lst1.Add(obj2);
lst1.Add(obj3);
List<item> lst2 = new List<item>();
lst2.Add(obj4);
lst2.Add(obj5);
lst2.Add(obj6);
now i want to add the value of the dictionary based on id of the object and the dictionary key. the result will be like this :
List<item> result = new List<item>();
result[0].Id = 1
result[0].Data["1"] = 52 // obj1.Data[1] + obj4.Data[1]
result[0].Data["2"] = 54 // obj1.Data[2] + obj4.Data[2]
result[0].Data["3"] = 56 // obj1.Data[3] + obj4.Data[3]
result[1].Id = 2
result[1].Data["1"] = 72 // obj2.Data[1] + obj5.Data[1]
result[1].Data["2"] = 74 // obj2.Data[2] + obj5.Data[2]
result[1].Data["3"] = 76 // obj2.Data[3] + obj5.Data[3]
result[2].Id = 3
result[2].Data["1"] = 92 // obj3.Data[1] + obj6.Data[1]
result[2].Data["2"] = 94 // obj3.Data[2] + obj6.Data[2]
result[2].Data["3"] = 96 // obj3.Data[3] + obj6.Data[3]
what is the best way to get this result ?
thanks
First of all, the output you shown as an example is wrong. For example, obj3.Data[1] + obj6.Data[1] equals to 92, not 56.
So, here it is with the all beauty of LINQ:
var result = lst1.Join(lst2, x => x.Id, y => y.Id, (x, y) => new item
{
Id = x.Id,
Data = x.Data.Join(y.Data,
a => a.Key,
b => b.Key,
(a, b) => new { a.Key, Value = a.Value + b.Value }).ToDictionary(r => r.Key, t => t.Value)
}).ToList();
As you want, the result is:
result[0].Id = 1
result[0].Data["1"] = 52 // obj1.Data[1] + obj4.Data[1]
result[0].Data["2"] = 54 // obj1.Data[2] + obj4.Data[2]
result[0].Data["3"] = 56 // obj1.Data[3] + obj4.Data[3]
result[1].Id = 2
result[1].Data["1"] = 72 // obj2.Data[1] + obj5.Data[1]
result[1].Data["2"] = 74 // obj2.Data[2] + obj5.Data[2]
result[1].Data["3"] = 76 // obj2.Data[3] + obj5.Data[3]
result[2].Id = 3
result[2].Data["1"] = 92 // obj3.Data[1] + obj6.Data[1]
result[2].Data["2"] = 94 // obj3.Data[2] + obj6.Data[2]
result[2].Data["3"] = 96 // obj3.Data[3] + obj6.Data[3]
Here's a much longer way to do it, but it does easily allow you the ability to add multiple lists of item lists with a single function, and is possibly easier to understand/debug depending on your Linq mastery:
private static List<Item> AddItemLists(List<List<Item>> itemLists)
{
if (itemLists == null) throw new ArgumentNullException("itemLists");
var result = new List<Item>();
foreach (var itemList in itemLists)
{
foreach (var item in itemList)
{
var existingItemWithId = result.FirstOrDefault(i => i.Id == item.Id);
if (existingItemWithId == null)
{
result.Add(item);
}
else
{
foreach (var itemData in item.Data)
{
if (existingItemWithId.Data.ContainsKey(itemData.Key))
{
existingItemWithId.Data[itemData.Key] += itemData.Value;
}
else
{
existingItemWithId.Data.Add(itemData.Key, itemData.Value);
}
}
}
}
}
return result;
}
Example usage:
var obj1 = new Item {Id = 1, Data =
new Dictionary<string, int> {{"1", 11}, {"2", 12}, {"3", 13}}};
var obj2 = new Item {Id = 2, Data =
new Dictionary<string, int> {{"1", 21}, {"2", 22}, {"3", 23}}};
var obj3 = new Item {Id = 3, Data =
new Dictionary<string, int> {{"1", 31}, {"2", 32}, {"3", 33}}};
var obj4 = new Item {Id = 1, Data =
new Dictionary<string, int> {{"1", 41}, {"2", 42}, {"3", 43}}};
var obj5 = new Item {Id = 2, Data =
new Dictionary<string, int> {{"1", 51}, {"2", 52}, {"3", 53}}};
var obj6 = new Item {Id = 3, Data =
new Dictionary<string, int> {{"1", 61}, {"2", 62}, {"3", 63}}};
// Three lists of items that we want to 'add'
var lst1 = new List<Item> {obj1, obj2};
var lst2 = new List<Item> {obj3, obj4};
var lst3 = new List<Item> {obj5, obj6};
// Add up as many lists of items that you want
var result = AddItemLists(new List<List<Item>> {lst1, lst2, lst3});
The results look like:
I have just recently been doing something in C#, i would like to know how to do something like this.
Array[0] =
Array['Value'] = 2344;
Array['LocationX'] = 0;
Array['LocationY'] = 0;
Array[1] =
Array['Value'] = 2312;
Array['LocationX'] = 2;
Array['LocationY'] = 1;
Array[2] =
Array['Value'] = 2334;
Array['LocationX'] = 4;
Array['LocationY'] = 3;
The data it self its not important, the thing is that i know how to do this in PHP. But in C# i don't, and I've tried some ways and no luck.
In PHP i could just do something like this:
$Array[0]->Value = 2344;
$Array[0]->LocationX = 0;
$Array[0]->LocationY = 0;
And those values would be added to the Array.
In C# i've tried this and doesn't work that way.
Could someone enlighten me in how to do this in C#?
Thanks.
Well, you could have an array of instances of a class that you write like so:
public class DataForArray
{
public int Value { get; set; }
public int LocationX { get; set; }
public int LocationY { get; set; }
}
Then something like this:
DataForArray[] array = new DataForArray[10];
array[0] = new DataForArray();
array[0].Value = 2344;
etc...
Either write a class or struct to hold Value, LocationX and LocationY.
struct Foo
{
Foo(value, x, y)
{
Value = value;
LocationX = x;
LocationY = y;
}
Foo() {}
int Value;
int LocationX;
int LocationY;
}
Foo[] f = new []
{
new Foo(1, 2, 3),
new Foo(2, 3, 4)
}
or alternatively initialize the array this way:
Foo[] f = new []
{
new Foo() { Value = 1, LocationX = 2, LocationY = 3 },
new Foo() { Value = 4, LocationX = 5, LocationY = 6 },
}
Or use an Array of Dictionary<string, int>.
Dictionary<string, int>[] array = new []
{
new Dictionary<string, int>() {{ "Value", 1 }, {"LocationX", 2}, {"LocationY", 3 }},
new Dictionary<string, int>() {{ "Value", 4 }, {"LocationX", 5}, {"LocationY", 6 }}
}
Which is only recommended if it needs to be dynamic (means: you want to have different values in each element of the array or your keys are in strings, not known at compile-time.) Unless it is just hard to maintain.
in C#, you can try something like this
// initialize array
var list = new[]
{
new {Value = 2344, LocationX = 0, LocationY = 0},
new {Value = 2312, LocationX = 2, LocationY = 4},
new {Value = 2323, LocationX = 3, LocationY = 1}
}.ToList();
// iterate over array
foreach (var node in list)
{
var theValue = node.Value;
var thePosition = new Point(node.LocationX, node.LocationY);
}
// iterate over array with filtering ( value > 2300 )
foreach (var node in list.Where(el => el.Value > 2300))
{
var theValue = node.Value;
var thePosition = new Point(node.LocationX, node.LocationY);
}
// add again
list.Add(new { Value = 2399, LocationX = 9, LocationY = 9 });
Here is a link that details the use of Multidimensional arrays
http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx
You can use anonymous type in C# like that:
var arr = new[] {
new{Value = 1, LocationX = 2, LocationY = 3},
new{Value = 1, LocationX = 2, LocationY = 3},
new{Value = 1, LocationX = 2, LocationY = 3},
new{Value = 1, LocationX = 2, LocationY = 3},
new{Value = 1, LocationX = 2, LocationY = 3} };
Only one problem is that properties in anonymous type are read-only. So You can't do something like that:
arr[1].Value = 2