1

私は次のSortedDictionaryを持っています:

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

dict には同じ値を持つリストがたくさんあります。LINQ を使用して、類似したリストを持つこれらすべての行を 1 つの行にまとめたいと考えています。ただし、各リストはオブジェクトであるため、LINQ はそれらすべてを個別のエンティティとして認識します。

私の質問は次のとおりです: GroupBy(grp => grp.Value) がリストオブジェクト自体ではなく、リストの内容によって実際に辞書をグループ化するようにコードを設定するにはどうすればよいですか?

4

1 に答える 1

3

またはIEqualityComparer<IList<string>>のようなほとんどの linq メソッドに使用できるカスタムを作成します。which implementsに対しても機能することに注意してください。GroupByDistinctstring[]IList<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;
    }
}

次に、次のクエリを使用して dictinct を作成できます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));

リスト内の文字列の順序が重要な場合でも、役立つ場合があります。

于 2013-03-08T22:47:58.867 に答える