Unique list of items using LINQ

后端 未结 6 1420
星月不相逢
星月不相逢 2021-02-01 05:39

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 = new Lis         


        
相关标签:
6条回答
  • 2021-02-01 05:44

    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();
    
    0 讨论(0)
  • 2021-02-01 05:46

    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();

    0 讨论(0)
  • 2021-02-01 05:58
    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()
    
    0 讨论(0)
  • 2021-02-01 06:04

    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".

    0 讨论(0)
  • 2021-02-01 06:08

    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();
    }
    
    0 讨论(0)
  • 2021-02-01 06:08
    var kitchenAppliances = stocks.Where(stock => stock.Type == "Kitchen Appliance");
    
    0 讨论(0)
提交回复
热议问题