簡體   English   中英

LINQ與基於List屬性的相應計數不同

[英]LINQ distinct with corresponding counts based on a List property

我有以下課程

public class Photo
{
    public int Id { get; set; }
    public string Caption { get; set; }
    public Collection<string> Tags { get; set; }
}

照片可以有多個與之關聯的標簽,並且相同的標簽可以用於任意數量的不同照片。

我最終想要做的是檢索不同標簽的列表,並計算為每個標簽分配的照片數量。

我無法控制底層數據 - 我正在使用一個API,它有一個我用來檢索照片集合的搜索方法,但沒有方法可以獲取不同標簽的列表。

所以我的問題是,如果我有大量的照片集,我如何使用LINQ獲取此列表中包含的標簽的明確列表,並獲取每個標簽的計數(照片)?

var tagCounts = photos
    .SelectMany(photo => photo.Tags)
    .GroupBy(tag => tag, (tag, group) => new { tag, count = group.Count() })
    .ToDictionary(tuple => tuple.tag, tuple => tuple.count);

推理如下。

  • 如果多張照片具有相同的標簽,則重復獲取所有標簽的序列。
  • 按重復標記的值對其進行分組,並計算每個組中的標記數。
  • 構造從每個標記到具有該標記的照片數量的字典映射。

您可以像這樣使用SelectManyGroupBy : -

var result = photos.SelectMany(x => x.Tags, (photosObj, tags) => new {photosObj, tags})
                   .GroupBy(x => x.tags)
                   .Select(x => new
                         {
                            Tags = x.Key,
                            PhotoId = String.Join(",",x.Select(z => z.photosObj.Id))
                         });

這將以逗號分隔格式為您提供所有標簽及其各自的PhotoIds

更新:

對不起,剛剛注意到你想要Photos對象的數量,在這種情況下你只需要這個: -

var result = photos.SelectMany(x => x.Tags)
                   .GroupBy(x => x)
                   .Select(x => new
                              {
                                  Tags = x.Key,
                                  PhotoCount = x.Count()
                              });

所以,假設你有這些數據: -

 List<Photo> photos = new List<Photo>
 {
     new Photo { Id =1, Caption = "C1", Tags = new List<string> { "T1", "T2", "T3" }},
     new Photo { Id =2, Caption = "C2", Tags = new List<string> { "T4", "T2", "T5" }},
     new Photo { Id =3, Caption = "C3", Tags = new List<string> { "T5", "T3", "T2" }}
 };

你將低於輸出: -

在此輸入圖像描述

你可以分兩步完成。

  • 首先從列表中獲取不同的標簽
  • 迭代不同的標簽並從列表中獲取計數並將其放入Dictionary<string,int>

就像是:

List<Photo> list = new List<Photo>();
var distinctTags = list.SelectMany(r => r.Tags).Distinct();
Dictionary<string, int> dictionary = new Dictionary<string, int>();
foreach (string tag in distinctTags)
{
    dictionary.Add(tag, list.Count(r=> r.Tags.Contains(tag)));
}
var list=new[]{
   new {id=1,Tags=new List<string>{"a","b","c"}},
   new {id=2,Tags=new List<string>{"b","c","d"}},
   new {id=3,Tags=new List<string>{"c","d","e"}},
};
var result=list.SelectMany(r=>r.Tags)
   .GroupBy(r=>r,r=>r,(Key,Vals)=>new {Tag=Key,Count=Vals.Count()});

結果:

Tag Count
a 1 
b 2 
c 3 
d 2 
e 1 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM