serhio
serhio

Reputation: 28586

Lambda expression question

string[] fruits = { "apple", "banana", "mango", "orange", 
                      "passionfruit", "grape" };

var query =
    fruits.Select((fruit, index) =>
                      new { index, str = fruit.Substring(0, index) });

foreach (var obj in query)
{
    Console.WriteLine("{0}", obj);
}

/*
 This code produces the following output:

 {index=0, str=}
 {index=1, str=b}
 {index=2, str=ma}
 {index=3, str=ora}
 {index=4, str=pass}
 {index=5, str=grape}
*/

Could somebody explain, how "index" is associated here as array index of the elements?

Say, I need a query that instead of first letter returns me the whole object (string in this case) + associated index.

Upvotes: 0

Views: 287

Answers (7)

user111013
user111013

Reputation:

Perhaps breaking down what this expression does will help you understand it:

fruits.Select((fruit, index) =>
                  new { index, str = fruit.Substring(0, index) });

Select(...) = With the input, return an output as indicated within.

(fruit, index) = Assign the selected fruit to the variable fruit, and the index (position in Enumerable) into index. As mentioned, this is simply one overload (option) available to you. If you don't care about the index value, simply omit it.

=> = return the following value

new { ... } = Create an instance of an anonymous type. This type will have two properties: index, and str. The value of index will be the variable index. the value of str will be the result of the substring on the fruit.

So, if you simply want the fruit, you could rewrite it like so:

fruits.Select(fruit => fruit); 

If you still want the index, with the full name of the fruit:

fruits.Select((fruit, index) =>
                  new { index, str = fruit});

Select is useful for returning a different set of information from what the input was.

By way of example using a slightly more complex scenario:

For instance, if you had classes like so:

public class Customer { 
 public int Id {get; set;}
 public string Name { get; set;}
 public List<Order> Orders { get; set;} 
} 

public class Order { 
 public int Id { get;set;} 
 public double TotalOrderValue { get;set}
} 

You could use a simple Select statement to return the customer, and the sum of how much that customer has ever ordered:

 var customersTotalSpend = customers.Select(
      customer => 
      new { 
            customer, 
            TotalSpend = customer.Orders.Select(order => order.TotalOrderValue).Sum()
           }); 

We could then do something with that TotalSpend value if we wanted, eg getting the 10 biggest spenders:

var biggestCustomers = customersTotalSpend.OrderByDescending(customerSpend=> customer.TotalSpend).Take(10); 

Does that make sense now?

Upvotes: 0

Yochai Timmer
Yochai Timmer

Reputation: 49269

The lambda expression populates the first variable name as the item itself, and the second as the index.

So if you have (fruit,index) then:

fruit = The data object.

index = The index in the array.

Upvotes: 1

LukeH
LukeH

Reputation: 269658

That's just how that particular overload of Select works: "the second parameter of the function represents the index of the source element".

If you want the entire string then you can do something like this:

var query = fruits.Select((fruit, index) => new { index, str = fruit });

Upvotes: 1

Jackson Pope
Jackson Pope

Reputation: 14660

Not quite sure what you're asking but try:

string[] fruits = { "apple", "banana", "mango", "orange", 
                      "passionfruit", "grape" };

var query =
    fruits.Select((fruit, index) =>
                      new { index, str = fruit });

foreach (var obj in query)
{
    Console.WriteLine("{0}", obj);
}

Index is used in an overload of Select to describe the index of the object your lambda is currently iterating over.

Upvotes: 1

Tim Lloyd
Tim Lloyd

Reputation: 38494

The index variable is simply a counter that increments from 0 as you iterate through the list of fruits. In this example there is a natural relationship between index and the position of fruit in fruits as you are iterating through fruits one element at a time.

I'm not sure about your question regarding access to 'the whole object'. You already have access to this:

var query = fruits.Select((fruit, index) => new { index, fruit });

fruit refers to the current element in fruits as you iterate through it.

Upvotes: 3

Lazarus
Lazarus

Reputation: 43124

To return the whole string in each case just modify the query thus:

var query =
    fruits.Select((fruit, index) =>
                  new { index, str = fruit });

index is just that, the array element index.

Upvotes: 1

Daniel A. White
Daniel A. White

Reputation: 191058

As for your first question, it is an overload for Select. See: http://msdn.microsoft.com/en-us/library/bb534869.aspx

Upvotes: 0

Related Questions