How to convert Array Objects into another using LINQ?

Go To StackoverFlow.com

3

I have a List of Anonymous objects containing following fields in C# derived from a LINQ query.

{ 
String category
decimal Jan
decimal Feb
decimal Mar
decimal Apr
decimal May
decimal Jun
decimal Jul
decimal Aug
decimal Sep
decimal Oct
decimal Nov
decimal Dec
}

how could I create a list of Objects having one field for each value of category ( so essentially 12 objects one object for each month( jan, feb, march etc.).

ExpectedResult {
string Month, 
decimal category1,
decimal category2,
decimal category3,
...
decimal categoryN
}

So result would have 12 objects of ExpectedResult. Not knowing how many categories/is a problem. Any quick suggestion would be helpful.

2012-04-04 21:18
by Kishor Patil
So the new object would look like var Jan = { Cat1Name = 1.3, Cat2Name = 15.5, Cat3Name = 90.6, ... }? What to do if the category name is not a valid C# identifier - mellamokb 2012-04-04 21:22
I would like to a var newItem = new { Month = Jan, Cat1Name = 1.3, cat2Name= 13.5... - Kishor Patil 2012-04-04 21:25
what's the original query - Phil 2012-04-04 21:29
Since the field names are going to be dynamically generated, it will be difficult to work with this anonymous object. What is the goal you are trying to accomplish? How will these new objects be used - mellamokb 2012-04-04 21:29
If you want to project the result into types with properties having the names the values from Category, then @mellamokb is righ - Adrian Iftode 2012-04-04 21:33
I would be converting the list to Json and pass it to javascript - Kishor Patil 2012-04-04 21:33


2

You can try a SelectMany() method:

anonymousList.SelectMany(x=>new[]{
                                    new {Cat=category, Month="Jan", Val=Jan}, 
                                    new {Cat=category, Month="Feb", Val=Feb}, 
                                    ... , 
                                    new {Cat=category, Month="Dec", Val=Dec}
                                 });

For each of your source anonymous objects, this query will produce an array of 12 new anonymous objects, and then those arrays (as Enumerables) will be concatenated into one large collection.

Just to avoid comparing strings later on, consider using an Enum for the months of the year (unfortunately .NET doesn't have one built-in):

public enum Month
{
   January = 1,
   February = 2,
   ...
   December = 12
}

...

anonymousList.SelectMany(x=>new[]{
                                    new {Cat=category, Month=Month.January, Val=Jan}, 
                                    new {Cat=category, Month=Month.February, Val=Feb}, 
                                    ... , 
                                    new {Cat=category, Month=Month.December, Val=Dec}
                                 });
2012-04-04 21:50
by KeithS
This is not what the OP needs. He wants several anonymous classes of the following definition: { public string Month, public decimal Category1, public decimal Category2, public decimal Category3 } where Category1..n are values from the previous query. Which is not possible (excluding emitting IL code :) - Adrian Iftode 2012-04-04 23:36
@KeithS, tried your solution. It creates multiple entries. What we expect is consolidated result of 12 records - one for each month. Unfortunately, I am not able to Group them once you create new category - Kishor Patil 2012-04-05 13:38


0

Starting from KeithS answer you could group this by months:

var results = from x in KeithsAnswer
              group x by x.Month into g
              select new { Month = g.Key, CategoryValues = g.Select(c => new { c.Month, c.Val }).ToArray()};

You can pass this directly to the client to process there or if you really need the form you specified above, you can implement your own JavaScriptConverter or use a dynamic/ExpandoObject to store the values as properties.

2012-04-04 22:31
by aKzenT
Ads