簡體   English   中英

按計數排序字符串集合列表,然后按字符串排序

[英]Order a list of Sorted Set of Strings by Count and then by strings

我有一個名為PairString

 public class PairString: IComparer<PairString>
    {
        public string first;
        public string second;
        public PairString(string f, string s)
        {
            first = f;
            second = s;
        }
        public int Compare([AllowNull] PairString x, [AllowNull] PairString y)
        {
            if (x == null || y == null) return -1;
            var f = string.Compare(x.first, y.first);
            var s = string.Compare(x.second, y.second);
            return f == s ? s : f;
        }
    }

我想按計數創建組,然后按該組中字符串的詞法順序,從輸入 PairString 列表的列表中創建組。 下面的方法進行分組。 但是,當我嘗試按相等計數組的詞法順序對組進行排序時,它會拋出“至少一個 object 必須實現 IComparer 錯誤”

public static List<string> MaxItemAssociatoinGroup(List<PairString> input)
        {
            if (input == null || input.Count == 0) return null;
            List<SortedSet<string>> output = new List<SortedSet<string>>();
            foreach (var item in input)
            {
                if (output.Any(x => x.Contains(item.first) || x.Contains(item.second)))
                {
                    //Take the set containing one or two or both items
                    var set1 = output.FirstOrDefault(x => x.Contains(item.first));
                    var set2 = output.FirstOrDefault(x => x.Contains(item.second));
                    if (set1 == null)
                        set2.UnionWith(new SortedSet<string> { item.first, item.second });

                    else if (set2 == null)
                        set1.UnionWith(new SortedSet<string> { item.first, item.second });

                    else if (set1 != set2)
                    {
                        set1.UnionWith(set2);
                        output.Remove(set2);
                    }
                }
                else
                    output.Add(new SortedSet<string>(new List<string>() { item.first, item.second }));
            }
            var maxlistAssociation = output.OrderByDescending(x => x.Count).First();
            return new List<string>(maxlistAssociation);
        }

我不確定如何為相同的計數組實現詞匯順序,樣本輸入是

new PairString("item3","item4"),
            new PairString("item3","item6"),
            new PairString("item5","item6"),
            new PairString("item2","item8"),
            new PairString("item8","item9"),
            new PairString("item1","item2")

它分為 2 組相等計數的{item3,item4,item5,item6} & {item1,item2,item8,item9}但返回{item3,item4,item5,item6}作為列表中的第一個。 但我想要第二組,因為它包含的項目按字典順序排在第一組之前。 我在這里錯過了什么?

看來您缺少一種方法,該方法將比較兩個SortedSet<string>對象並返回詞法上第一個出現的對象。 一種方法是將一組中的每個項目與另一組中的相應項目進行比較,並返回第一個不相等的比較:

public class SortedSetComparer<T> : IComparer<SortedSet<T>> where T : IComparable<T>
{
    public int Compare(SortedSet<T> x, SortedSet<T> y)
    {
        // Null checks
        if (x == null) return y == null ? 0 : 1;
        if (y == null) return -1;

        var minCount = Math.Min(x.Count, y.Count);

        // Compare each item from one set with the corresponding one in the other set
        for (var i = 0; i < minCount; i++)
        {
            var result = x.ElementAt(i).CompareTo(y.ElementAt(i));

            // Return the first non-equal result
            if (result != 0) return result;
        }

        // If all the items were equal, return the comparison of the Count
        return x.Count.CompareTo(y.Count);
    }
}

然后我們可以通過將此 class 的實例傳遞給ThenBy方法來對結果進行排序(按大小排序后):

var maxlistAssociation = output
    .OrderByDescending(x => x.Count)
    .ThenBy(x => x, new SortedSetComparer<string>())
    .First();

根據您希望從該方法獲得的行為,我們還可以將按Count排序合並到我們的比較方法中,以便它將具有最多項目的集合放在第一位,然后按字母順序對它們進行排序:

public class SortedSetComparer<T> : IComparer<SortedSet<T>> where T : IComparable<T>
{
    public int Compare(SortedSet<T> x, SortedSet<T> y)
    {
        // Null checks
        if (x == null) return y == null ? 0 : 1;
        if (y == null) return -1;

        // Compare the counts first, in descending order
        var countComparison = x.Count.CompareTo(y.Count);
        if (countComparison != 0) return countComparison * -1;

        // Then compare each item from one set lecially 
        // with the corresponding one in the other set
        return x.Select((item, index) =>
            x.ElementAt(index).CompareTo(y.ElementAt(index)))
            .FirstOrDefault(result => result != 0);
    }
}

現在我們只需要一個OrderBy子句:

var maxlistAssociation = output
    .OrderBy(x => x, new SortedSetComparer<string>())
    .First();

暫無
暫無

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

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