LINQ与基于List属性的相应计数不同

时间:2015-04-30 19:19:41

标签: c# .net linq

我有以下课程

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

照片可以有多个与之关联的标签,同一个标签可用于任意数量的不同照片。

我最终想要做的是检索不同标签的列表,并计算每个标签分配的照片数量。

我无法控制基础数据 - 我使用的是一个API,它有一个我用来检索照片集合的搜索方法,但没有方法可以获取不同标记的列表。

所以我的问题是,如果我有大量的照片集合,我如何使用LINQ获取此列表中包含的标签的明确列表,并获取每个标签的计数(照片)? / p>

4 个答案:

答案 0 :(得分:8)

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

推理如下。

  • 获取所有标签的序列,如果多张照片具有相同的标签,则重复这些标签。
  • 按重复标记的值对其进行分组,并计算每个组中的标记数。
  • 构建从每个标记到具有该标记的照片数量的字典映射。

答案 1 :(得分:2)

您可以使用SelectMany&amp; GroupBy是这样的: -

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" }}
 };

您将在以下输出: -

enter image description here

答案 2 :(得分:0)

您可以分两步完成。

  • 首先从列表中获取不同的标签
  • 遍历不同的代码并从列表中获取计数并将其放入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)));
}

答案 3 :(得分:0)

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 
相关问题