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"开发者_StackOverflow 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.
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.
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.
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.
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 });
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.
As for your first question, it is an overload for Select
. See: http://msdn.microsoft.com/en-us/library/bb534869.aspx
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?
精彩评论