【发布时间】:2011-01-26 09:40:20
【问题描述】:
我已经阅读了许多关于 select 的站点/线程,并在 LINQ 中选择了许多,但仍然不太明白。
select 是否返回集合中的一个元素并选择多个扁平集合(例如 List>())?
谢谢
【问题讨论】:
-
欺骗问题 - 请参阅 stackoverflow.com/questions/958949/… 以获得很好的答案。
标签: linq
我已经阅读了许多关于 select 的站点/线程,并在 LINQ 中选择了许多,但仍然不太明白。
select 是否返回集合中的一个元素并选择多个扁平集合(例如 List>())?
谢谢
【问题讨论】:
标签: linq
这是一个示例。希望它能澄清一切:
static void MethodRun()
{
List<Topping> testToppings = new List<Topping> { Topping.Cheese, Topping.Pepperoni, Topping.Sausage };
var firstLetterofToppings = testToppings.Select(top => top.ToString().First());
// returns "C, P, S"
var singleToppingPizzas = testToppings.Select(top => new Pizza(top)).ToArray();
// returns "Pizza(Cheese), Pizza(Pepperoni), Pizza(Sausage)"
List<Topping> firstPizza = new List<Topping> { Topping.Cheese, Topping.Anchovies };
List<Topping> secondPizza = new List<Topping> { Topping.Sausage, Topping.CanadianBacon, Topping.Pepperoni };
List<Topping> thirdPizza = new List<Topping> { Topping.Ham, Topping.Pepperoni };
List<IEnumerable<Topping>> toppingsPurchaseOrder = new List<IEnumerable<Topping>> { firstPizza, secondPizza, thirdPizza };
var toppingsToOrder = toppingsPurchaseOrder.SelectMany(order => order);
//returns "Cheese, Anchovies, Sausage, CanadianBacon, Pepperoni, Ham, Pepperoni"
}
class Pizza
{
public List<Topping> Toppings { get; private set; }
public Pizza(Topping topping) : this(new List<Topping> { topping }) { }
public Pizza(IEnumerable<Topping> toppings)
{
this.Toppings = new List<Topping>();
this.Toppings.AddRange(toppings);
}
}
enum Topping
{
Cheese,
Pepperoni,
Anchovies,
Sausage,
Ham,
CanadianBacon
}
关键是 Select() 可以选择任何类型的对象。确实,您可以选择分配给您的集合的任何通用值的属性,但您也可以选择任何其他类型的对象。 SelectMany() 只是将您的列表变平。
【讨论】:
SelectMany 为传递到表达式中的每个对象返回一个对象数。 Select 会为传入表达式的每个对象返回一个单个对象。
引用文档:
多选
将序列的每个元素投影到 IEnumerable)>) 并将结果序列展平为一个序列。
选择
将序列的每个元素投影到一个新的形式中。
如果您想扁平化层次结构,可以使用SelectMany。例如。如果你有Orders 和OrderDetails。如果您想根据订单进行选择,但您想返回 OrderDetails,请使用 SelectMany。
var result = db.Orders
.Where(x => x.CustomerId == 500) // input to next expression is IEnumerable<Order>
.SelectMany(x => x.OrderDetails) // input to next expression is IEnumerable<OrderDetails>
.Sum(x => x.PositionTotal);
var result = db.Orders
.Where(x => x.CustomerId == 500) // input to next expression is IEnumerable<Order>
.Select(x => CustomerName);
【讨论】:
让我们依次回答您的问题:
1. select 是否返回集合中的一个元素? -> 不,绝对不是。 'select' 返回集合中完全相同数量的元素,但形状不同(如果需要)。
但是,是的,它返回一个包含所有这些元素的序列(/collection)(例如,下例中的 even_sqare)。
例如int[] even = {2,4};
int[] even_square = even.Select(n=> n*2).ToArray();
o/p
even_square 输出到{4,8},这与计数 (2) 完全相同,但投影不同,我们通过选择它们来给出每个平方。
2。 & 是否选择许多展平集合(例如 List>())?
-> 是的,但实际上,它就像我们的控件的交叉连接。
int[] odd = { 1, 3 };
int[] even = { 2, 4 };
int[] crossjoin =
even.SelectMany(
n => odd, //combining even with odd
(n,o)=>Convert.ToInt32(n.ToString()+o.ToString())//given many selects, decide our projection
).ToArray();
foreach (var item in crossjoin)
{
Console.WriteLine(item);
}
Output: 21
23
41
43
现在价值百万的东西:
【讨论】: