使用 LINQ 的唯一项目列表

发布于 2024-09-08 01:28:11 字数 1020 浏览 5 评论 0原文

我已经使用 LINQ 一段时间了,但似乎被困在有关唯一项目的问题上,我有以下列表:

List<Stock> stock = new List<Stock>();

它具有以下属性:字符串 ID 、字符串类型、字符串描述,示例:

public class Stock
{
    public string ID { get; set; }
    public string Type { get; set; }
    public string Description { get; set; }
}

我想要有一个 LINQ 查询,它将按类型对库存中的项目进行分组,并将其作为新的库存列表返回(它必须与原始库存列表的类型相同)。

示例数据:

 ID   Type                 Description
----------------------------------------------
  1   Kitchen Appliance    Dishwasher  
  2   Living Room          Television  
  3   Kitchen Appliance    Washing Machine  
  4   Kitchen Appliance    Fridge  

...

我的 Linq 查询希望能够返回示例中的所有厨房用具。
所以我会将其作为“类型”传递到查询中,它将返回项目 1、3 和 4 从此示例列表中。

返回的此列表还必须是以下类型:List

本质上,我想要按类型列出唯一项的列表,有点像 SQL 不同查询,如何在 LINQ 中实现此目的?
替代解决方案也可以,但必须仅为 Silverlight/C# 客户端代码。

另一个澄清是,我也可能不提供参数“厨房电器”,可能只想要独特的参数,例如,它只会返回厨房电器和客厅一次,就像一个类别,无论该类型有多少个有。

I've been using LINQ for a while now, but seem to be stuck on something with regards to Unique items, I have the folling list:

List<Stock> stock = new List<Stock>();

This has the following Properties: string ID , string Type, string Description, example:

public class Stock
{
    public string ID { get; set; }
    public string Type { get; set; }
    public string Description { get; set; }
}

I want to have a LINQ query that will group the items in Stock by their Type and return this as a new List of Stock (it has to be the same type as the original Stock List).

Example Data:

 ID   Type                 Description
----------------------------------------------
  1   Kitchen Appliance    Dishwasher  
  2   Living Room          Television  
  3   Kitchen Appliance    Washing Machine  
  4   Kitchen Appliance    Fridge  

...

My Linq query wants to be able to return all the Kitchen Appliances for Example.
So I would pass this as a "type" into the query and it would return the items 1, 3 and 4
from this example list.

This list returned must also be of type: List<Stock>.

Essentially I want a list of the unique items by type, kind of like an SQL Distinct query, how do I achieve this in LINQ?
Alternative solutions are fine but must be Silverlight / C# client code only.

Just another clarification is that I also may not provide the parameter "Kitchen Appliance" and may just want the unique ones, for example It would return Kitchen Appliance and Living Room once each only to kind of like a category no matter how many of that Type there are.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

无尽的现实 2024-09-15 01:28:11

灵活的方法

使用 GroupByToDictionary 创建 ListToDictionary 的字典Stock> 值在 Type 属性上键入:

var appliancesByType = stock
    .GroupBy(item => item.Type)
    .ToDictionary(grp => grp.Key, grp => grp.ToList());

然后您可以轻松访问类型本身以及任何给定类型的列表:

// List of unique type names only
List<string> stockTypes = appliancesByType.Keys.ToList();

// Or: list of one stock item per type
List<Stock> exampleStocks = appliancesByType
    .Select(kvp => kvp.Value[0])
    .ToList();

// List of stock items for a given type
List<Stock> kitchenAppliances = appliancesByType["Kitchen Appliance"];

这种方法确实可以满足您的所有需求,因为我看到了。但对于其他一些选项,请参见下文。

替代(快速和肮脏)方法

您始终可以使用 Where获取所需类型的项目,然后 ToList 将这些项目放入新的 List 中:

List<Stock> kitchenAppliances = stock
    .Where(item => item.Type == "Kitchen Appliance")
    .ToList();

响应最后一部分:

另一个澄清是我
也可能不提供参数
“厨房电器”可能只是想要
独特的,例如它会
返回 厨电生活
房间每人一次就有点像
类别,无论其中有多少个
类型有。

在这里,您似乎想要完全不同的东西:基本上是 独特。对于此功能,您基本上可以使用Soonts的答案( (可选)返回 IEnumerable 而不是 IEnumerable),或者您可以将 DistinctSelect 以避免需要实现 IEqualityComparer< ;库存>(见下文)。


更新

为了回应您的澄清,这是我的建议:两种方法,一种用于每个目的(单一责任原则):

// This will return a list of all Stock objects having the specified Type
static List<Stock> GetItemsForType(string type)
{
    return stock
        .Where(item => item.Type == type)
        .ToList();
}

// This will return a list of the names of all Type values (no duplicates)
static List<string> GetStockTypes()
{
    return stock
        .Select(item => item.Type)
        .Distinct()
        .ToList();
}

Flexible approach

Use GroupBy and ToDictionary to create a dictionary of List<Stock> values keyed on the Type property:

var appliancesByType = stock
    .GroupBy(item => item.Type)
    .ToDictionary(grp => grp.Key, grp => grp.ToList());

Then you can access the types themselves as well as a list for any given type quite easily:

// List of unique type names only
List<string> stockTypes = appliancesByType.Keys.ToList();

// Or: list of one stock item per type
List<Stock> exampleStocks = appliancesByType
    .Select(kvp => kvp.Value[0])
    .ToList();

// List of stock items for a given type
List<Stock> kitchenAppliances = appliancesByType["Kitchen Appliance"];

This approach really takes care of all your needs, as I see it. But for some other options, see below.

Alternate (quick & dirty) approach

You can always just use Where to get the items of the type you want, then ToList to put these items in a new List<Stock>:

List<Stock> kitchenAppliances = stock
    .Where(item => item.Type == "Kitchen Appliance")
    .ToList();

In response to this last part:

Just another clarification is that I
also may not provide the parameter
"Kitchen Appliance" and may just want
the unique ones, for example It would
return Kitchen Appliance and Living
Room once each only to kind of like a
category no matter how many of that
Type there are.

Here, you seem to be wanting something completely different: basically the behavior provided by Distinct. For this functionality, you could essentially go with Soonts's answer (optionally, returning an IEnumerable<tKey> instead of IEnumerable<tSource>), or you could just leverage Distinct in combination with Select to avoid the need to implement an IEqualityComparer<Stock> (see below).


Update

In response to your clarification, here's my recommendation: two methods, one for each purpose (Single Responsibility Principle):

// This will return a list of all Stock objects having the specified Type
static List<Stock> GetItemsForType(string type)
{
    return stock
        .Where(item => item.Type == type)
        .ToList();
}

// This will return a list of the names of all Type values (no duplicates)
static List<string> GetStockTypes()
{
    return stock
        .Select(item => item.Type)
        .Distinct()
        .ToList();
}
夏夜暖风 2024-09-15 01:28:11

听起来这是一个简单的Where 子句。

List<Stock> kitchen= stock.Where(s=>s.Type=="Kitchen Appliance")
                          .OrderBy(s=>s.Description).ToList();

如果您严格想要源列表中包含的 Types

string[] typesFound = stock.Select(s=>s.Type).Distinct().ToArray();

Sounds like it's a simple Where clause needed.

List<Stock> kitchen= stock.Where(s=>s.Type=="Kitchen Appliance")
                          .OrderBy(s=>s.Description).ToList();

If you wanted strictly the Types contained in the source list:

string[] typesFound = stock.Select(s=>s.Type).Distinct().ToArray();

枉心 2024-09-15 01:28:11
static class EnumerableEx
{
    // Selectively skip some elements from the input sequence based on their key uniqueness.
    // If several elements share the same key value, skip all but the 1-st one.
    public static IEnumerable<tSource> uniqueBy<tSource, tKey>( this IEnumerable<tSource> src, Func<tSource, tKey> keySelecta )
    {
        HashSet<tKey> res = new HashSet<tKey>();
        foreach( tSource e in src )
        {
            tKey k = keySelecta( e );
            if( res.Contains( k ) )
                continue;
            res.Add( k );
            yield return e;
        }
    }
}

// Then later in the code
List<Stock> res = src.uniqueBy( elt => elt.Type ).ToList()
static class EnumerableEx
{
    // Selectively skip some elements from the input sequence based on their key uniqueness.
    // If several elements share the same key value, skip all but the 1-st one.
    public static IEnumerable<tSource> uniqueBy<tSource, tKey>( this IEnumerable<tSource> src, Func<tSource, tKey> keySelecta )
    {
        HashSet<tKey> res = new HashSet<tKey>();
        foreach( tSource e in src )
        {
            tKey k = keySelecta( e );
            if( res.Contains( k ) )
                continue;
            res.Add( k );
            yield return e;
        }
    }
}

// Then later in the code
List<Stock> res = src.uniqueBy( elt => elt.Type ).ToList()
酸甜透明夹心 2024-09-15 01:28:11
var kitchenAppliances = stocks.Where(stock => stock.Type == "Kitchen Appliance");
var kitchenAppliances = stocks.Where(stock => stock.Type == "Kitchen Appliance");
箹锭⒈辈孓 2024-09-15 01:28:11

我可能不明白这个问题,但这对我来说听起来像一个非常简单的 Linq 查询:

List<Stock> stock = new List<Stock>();
... populate your list as per your example

List<Stock> kitchenAppliances =
    (from obj in stock
     where obj.Type == "Kitchen Appliance"
     select obj).ToList();

或者如果您更喜欢扩展方法语法:

List<Stock> kitchenAppliances =
    stock.Where(obj => obj.Type == "Kitchen Appliance").ToList();

我不明白的是您在这种情况下对 unique 和 unique 的使用。这些对象已经是唯一的,在我看来,您想要一个基本查询“给我所有厨房用具”。

I probably don't understand the question, but this sounds to me like a pretty simple Linq-query:

List<Stock> stock = new List<Stock>();
... populate your list as per your example

List<Stock> kitchenAppliances =
    (from obj in stock
     where obj.Type == "Kitchen Appliance"
     select obj).ToList();

or if you prefer the extension-method syntax:

List<Stock> kitchenAppliances =
    stock.Where(obj => obj.Type == "Kitchen Appliance").ToList();

What I don't understand is your usage of distinct and unique in this context. The objects are already unique, and it seems to me that you want a basic query "give me all kitchen appliances".

情场扛把子 2024-09-15 01:28:11

您也可以按照这些思路做一些事情,在这种情况下,我将获取 lucene 结果,然后将 umbraco 节点拉出为匿名类型

var datasource = (from n in SearchResults
select new
{
  PageLink = uQuery.GetNode(n.Id).NiceUrl,
  uQuery.GetNode(n.Id).Name,
  Date =    uQuery.GetNode(n.Id).GetProperty("startDate"),
  IntroText = string.IsNullOrEmpty(uQuery.GetNode(n.Id).GetProperty("introText").Value) ? string.Empty : uQuery.GetNode(n.Id).GetProperty("introText").Value,
  Image = ImageCheck(uQuery.GetNode(n.Id).GetProperty("smallImage").Value)

}).Distinct().ToList();

You could also do something along these lines, in this case I am taking lucene results then pulling off umbraco nodes to an anonymous type

var datasource = (from n in SearchResults
select new
{
  PageLink = uQuery.GetNode(n.Id).NiceUrl,
  uQuery.GetNode(n.Id).Name,
  Date =    uQuery.GetNode(n.Id).GetProperty("startDate"),
  IntroText = string.IsNullOrEmpty(uQuery.GetNode(n.Id).GetProperty("introText").Value) ? string.Empty : uQuery.GetNode(n.Id).GetProperty("introText").Value,
  Image = ImageCheck(uQuery.GetNode(n.Id).GetProperty("smallImage").Value)

}).Distinct().ToList();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文