使用LINQ对List

本文关键字:string List LINQ 使用 | 更新日期: 2023-09-27 18:03:07

我有以下SortedDictionary:

SortedDictionary<string, List<string>> dict 
            = (SortedDictionary<string,List<string>>) MyObj.GetDict();

dict中有许多具有相同值的列表,我想使用LINQ将具有相似列表的所有行折叠成一行。但是,每个列表都是一个对象,因此LINQ将它们视为不同的实体。

我的问题是:我如何设置我的代码,以便GroupBy(grp => grp. value)实际上按列表的内容分组字典,而不是列表对象本身?

使用LINQ对List<string>值

创建一个自定义的IEqualityComparer<IList<string>>,您可以使用大多数linq方法,如GroupByDistinct。注意,它也适用于实现IList<string>string[]:

public class IgnoreOrderComparer : IEqualityComparer<IList<string>>
{
    public IgnoreOrderComparer(StringComparer comparer)
    {
        this.Comparer = comparer;
    }
    public StringComparer Comparer { get; set; }
    public bool Equals(IList<string> x, IList<string> y)
    {
        if (x == null || y == null) return false;
        // remove the Distincts if there are never duplicates as mentioned
        return !x.Distinct(Comparer).Except(y.Distinct(Comparer), Comparer).Any();
        // btw, this should work if the order matters:
        // return x.SequenceEqual(y, Comparer);
    }
    public int GetHashCode(IList<string> arr)
    {
        if (arr == null) return int.MinValue;
        int hash = 19;
        foreach (string s in arr.Distinct(Comparer))
        {
            hash = hash + s.GetHashCode();
        }
        return hash;
    }
}

那么你可以使用下面的查询来创建一个指令集SortedDictionary<string, List<string>>

样本数据:

SortedDictionary<string, List<string>> dict = new SortedDictionary<string, List<string>>();
dict.Add("A", new List<string>() { "A", "B" });
dict.Add("B", new List<string>() { "B", "B" });
dict.Add("C", new List<string>() { "A", "B" });
dict.Add("D", new List<string>() { "C", "E" });
dict.Add("E", new List<string>() { "E", "C" });

首先在列表上使用Distinct,然后将它们与原始字典连接,最后创建一个新字典:

var comparer = new IgnoreOrderComparer(StringComparer.OrdinalIgnoreCase);
var uniqueLists = dict.Values.Distinct(comparer);
var uniqueDict = from list in uniqueLists
                 join kvp in dict 
                 on list equals kvp.Value
                 select kvp;
dict = new SortedDictionary<string,List<string>>(uniqueDict.ToDictionary(kv => kv.Key, kv => kv.Value));

即使列表中字符串的顺序很重要,它也可能很有帮助。