7

目标

获取 a 返回的每个结果之一foreach

场景

看一下以下 Razor 的代码片段:

@foreach (var product in Model.Collection.Products)
{
    <p>@product.name</p>
}

给客户的回报是:

Xbox 360

Xbox 360

Xbox 360

Xbox 360

游戏机 3

游戏机 3

游戏机 3

现在,让我解释一下:我的应用程序比较不同商店的产品价格。就我而言,四家商店有 Xbox 360,而三家商店有 Playstation 3——这就是他们的名字重复的原因。

我想要的很简单:一次获取每个产品的名称来填充 HTML 的表格列——你们都明白吗?

哲学

每个产品都添加到 Session 上。在我们的例子中,会话中有两个产品——第一个是Xbox 360,第二个是Playstation 3。所以,正如你所看到的,我可以使用 Session 来处理这个(“对于 Session 上的每个项目,做一些事情......”),但我认为这没有必要,因为我总是必须在数据库,从逻辑上讲,它返回了我需要的东西。换句话说,我不需要使用 Session 除了临时存储用户需要的东西。

聚光灯

Model.Collection.Products类型List<Products>

我尝试了什么?

像这样的东西:

@foreach (var product in Model.Collection.Products.FirstOrDefault())
{
    [...]
}

但是,当然,不成功。基本上我需要类似FirstOfEach().

4

5 回答 5

12

解决方案

使用GroupBy...

@foreach (var group in Model.Collection.Products.GroupBy(x => x.name))
{
    <p>@group.Key</p>
}

AGroupBy将返回一个属性代表您分组的属性的值(在这种情况IEnumerable<IGrouping<TKey, TSource>>下:)Keyname


其他福利

这种方法的好处是您还可以访问每个组的项目,因此如果您想列出每个组的不同价格,例如,您可以执行以下操作:

@foreach (var group in Model.Collection.Products.GroupBy(x => x.name))
{
    <p>Product: @group.Key (@group.Count() items)</p>
    <p>Prices: 
    @foreach(var item in group)
    {
        <span>@item.price</span>
    }
    </p>
}

(我知道这不是最好的 HTML,它只是一个使用示例!)

于 2013-08-06T14:50:00.217 回答
7

你需要DistinctBy

@foreach (var product in Model.Collection.Products.DistinctBy(p=>p.name))

public static partial class MyExtensions
{
    public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> keySelector)
    {
        HashSet<TKey> knownKeys = new HashSet<TKey>();
        return source.Where(x => knownKeys.Add(keySelector(x)));
    }
}
于 2013-08-06T14:50:34.853 回答
1

如果您想要的只是不同的产品名称,您可以从集合中提取不同的列表:

@foreach (var productName in Model.Collection.Products.Select(p=>p.Name).Distinct())
{
    <p>@productName</p>
}
于 2013-08-06T14:52:40.710 回答
1

You should implement this in conjunction with

foreach (var product in Model.Collection.Products.Distinct())

and

public class Products : IEquatable<Products>
{
    public string Name { get; set; }  //your properties

    public bool Equals(Products other)
    {

        //Check whether the compared object is null. 
        if (Object.ReferenceEquals(other, null)) return false;

        //Check whether the compared object references the same data. 
        if (Object.ReferenceEquals(this, other)) return true;

        //Check whether the products' properties are equal. 
        return Name.Equals(other.Name);
    }

    // If Equals() returns true for a pair of objects  
    // then GetHashCode() must return the same value for these objects. 

    public override int GetHashCode()
    {

        //Get hash code for the Name field if it is not null. 
        int hashProductName = Name == null ? 0 : Name.GetHashCode();  


        //Calculate the hash code for the product. 
        return hashProductName ;
    }
}
于 2013-08-06T14:53:42.420 回答
0

与 GroupBy 类似,您还可以将列表转换为 Lookup

Model.Collection.Products.ToLookup(x => x.name))
于 2013-08-06T15:01:59.677 回答