查找相等的字符串集合及其计数(不同列表)

本文关键字:列表 字符串 集合 查找 | 更新日期: 2023-09-27 17:49:35

我正在尝试找到不同的集合和它们的计数。

假设您有以下模型。

public class AModel {
   public IList<string> Tags { get; set; }
}

并且你有上述模型的列表,假设有50,000个AModel的实例,其中1…N Tags .

我需要使用高性能LINQ找到不同的Tags,列表不列表值(顺序无关紧要,计数和标记字符串问题)。

的例子:

List<AModel> models = new List<AModel>{
   new AModel { Tags = new List<string> { "Tag1", "Tag2" } },
   new AModel { Tags = new List<string> { "Tag2", "Tag1" } },
   new AModel { Tags = new List<string> { "Tag1", "Tag1" } },
   new AModel { Tags = new List<string> { "Tag2", "Tag2" } },
   new AModel { Tags = new List<string> { "Tag2", "Tag2" } },
};
所以,我需要一个结果:

List: { "Tag1", "Tag2" } Count: 2
List: { "Tag1", "Tag1" } Count: 1
List: { "Tag2", "Tag2" } Count: 2

我已经检查到目前为止,SetEquals和SequenceEquals。我可以迭代到所有模型的所有标签,并保持相等的计数和集合,如果我已经检查过它,则传递下一个,但它是计数器效率。

查找相等的字符串集合及其计数(不同列表)

实现EqualityComparer<IList<string>>

public override bool Equals(IList<string> x, IList<string> y)
{
    return Enumerable.SequenceEqual(x.OrderBy(i => i), y.OrderBy(i => i));
}
public override int GetHashCode(IList<string> obj)
{
    return obj.Select(i => i.GetHashCode()).Average().GetHashCode();
}

在linq groupby

中使用
List<AModel> models = new List<AModel>() {
    new AModel { Tags = new List<string> { "Tag1", "Tag2" } },
    new AModel { Tags = new List<string> { "Tag2", "Tag1" } },
    new AModel { Tags = new List<string> { "Tag1", "Tag1" } },
    new AModel { Tags = new List<string> { "Tag2", "Tag2" } },
    new AModel { Tags = new List<string> { "Tag2", "Tag2" } },
};
var result = models
    .GroupBy(i => i.Tags, new ListEqualityComparer())
    .Select(i => new { Tags = i.Key, Count = i.Count() });

我处理这个问题的方法是先对标签进行排序,然后将它们组合成一个唯一的键,然后我可以使用行来分组。分组应该自动为我提供密钥和计数。

这是一个初稿,让你开始:

foreach(var value in models.Select(model => String.Join(";", model.Tags.OrderBy(tags => tags))).GroupBy(list => list))
{
     Console.WriteLine(value.Key + "," + value.Count());
}

输出与您想要的非常相似:

标签1,标签2 2
标签1;标签1,1
标签2,标签2 2