markzzz
markzzz

Reputation: 47995

How to pass the current index iteration inside a select new MyObject

This is my code:

infoGraphic.chartData = (from x in db.MyDataSource
                         group x by x.Data.Value.Year into g
                         select new MyObject
                         {
                             index = "", // here I need a string such as "index is:" + index
                             counter = g.Count()
                         });

I need the current index iteration inside the select new. Where do I pass it?

EDIT - My current query:

var test = db.MyData
            .GroupBy(item => item.Data.Value.Year)
            .Select((item, index ) => new ChartData()
            {
                index = ((double)(3 + index ) / 10).ToString(),
                value = item.Count().ToString(),
                fill = index.ToString(),
                label = item.First().Data.Value.Year.ToString(),
            }).ToList();

public class ChartData
{
    public string index { get; set; }
    public string value { get; set; }
    public string fill { get; set; }
    public string label { get; set; }
}

Upvotes: 5

Views: 2787

Answers (2)

Veverke
Veverke

Reputation: 11368

Use IEnumerable extension methods, I think the syntax is more straightforward. You need the 2nd overload, that receives the IEnumerable item and the index.

infoGraphic.chartData.Select((item, index) => {
   //what you want to do here
});

You want to apply grouping on your chartData, and afterwards select a subset / generate a projection on the resulting data ?

your solution should look like:

infoGraphic.chartData
    .GroupBy(...)
    .Select((item, index) => {
      //what you want to do here
});

abstracting the dataSource as x:

x.GroupBy(item => item.Data.Value.Year)
 .Select((item, index) => new { index = index, counter = item.Count() });

As a follow up to your new question... here is a simple working scenario with a custom type (like your ChartData):

class Program
{
    static void Main(string[] args)
    {
        List<int> data = new List<int> { 1, 872, -7, 271 ,-3, 7123, -721, -67, 68 ,15 };

        IEnumerable<A> result = data
            .GroupBy(key => Math.Sign(key))
            .Select((item, index) => new A { groupCount = item.Count(), str = item.Where(i => Math.Sign(i) > 0).Count() == 0 ? "negative" : "positive" });

        foreach(A a in result)
        {
            Console.WriteLine(a);
        }
    }
}

public class A
{
    public int groupCount;
    public string str;

    public override string ToString()
    {
        return string.Format("Group Count: [{0}], String: [{1}].", groupCount, str);
    }
}

/* Output:
*  -------
*  Group Count: [6], String: positive
*  Group Count: [4], String: negative
*/

Important: Make sure the data type you are to use the extension methods is of type IEnumerable (inherits IEnumerable), otherwise you will not find this Select overload my solution is talking about, exposed.

Upvotes: 9

Bernard Oreva
Bernard Oreva

Reputation: 118

you can do something like this:

let currIndex = collection.IndexOf(collectionItem)

Your code would then become:

infoGraphic.chartData =

(from x in db.MyDataSource group x by x.Data.Value.Year into g

                         // Get Iterator Index Here
                         let currIndex = db.MyDataSource.IndexOf(x)

                         select new MyObject
                         {index = currIndex.ToString(), // Your Iterator Index
counter = g.Count()
                         });

Upvotes: 0

Related Questions