C# 在C中对嵌套字符串列表进行排序#

C# 在C中对嵌套字符串列表进行排序#,c#,sorting,C#,Sorting,我想要实现的是一个按字母顺序排序的嵌套列表 例如,我的输入: fat, twat, gat //Line 1 cat, hat, bat // Line 2 twat, lack, rat // Line 3 我希望输出为: bat, cat, hat // Line 2 fat, gat, twat // Line 1 lack, rat, twat // Line 3 如您所见,列表首先在内部排序,然后在外部排序 我目前的实现是使用嵌套列表: List<

我想要实现的是一个按字母顺序排序的嵌套列表

例如,我的输入:

fat, twat, gat    //Line 1
cat, hat, bat     // Line 2
twat, lack, rat   // Line 3
我希望输出为:

bat, cat, hat    // Line 2
fat, gat, twat   // Line 1
lack, rat, twat  // Line 3
如您所见,列表首先在内部排序,然后在外部排序

我目前的实现是使用嵌套列表:

List<List<String>> testSort;
列表测试排序;
我已使用以下方法对内部列表进行排序:

    public static List<List<String>> sortList(List<List<String>> input)
    {
        input.ForEach(delegate (List<string> o)
        {
            o.Sort();
        });

        return input;
    }
公共静态列表排序列表(列表输入)
{
input.ForEach(委托(列表o)
{
o、 排序();
});
返回输入;
}
我不确定现在如何对外部列表进行排序。谢谢你的帮助

提前谢谢

在对每个内部列表进行排序后,可以使用OrderBy()根据每个列表的第一个元素对外部列表进行排序:

input.ForEach(t => t.Sort());
input = input.OrderBy(t => t.First()).ToList();
对于M.kazem Akhgary下面的评论,如果您希望外部列表的排序不仅基于第一个元素,而且基于整个列表,我只能想到这个解决方案。也许其他人有更好的解决办法

input.ForEach(t => t.Sort());
input.Sort((e1, e2) => {
    for (int i = 0; i < e1.Count; i++)
    {
        if(e1[i] != e2[i])
        {
            return e1[i].CompareTo(e2[i]);
        }
    }

    return 0;
});
input.ForEach(t=>t.Sort());
输入.排序((e1,e2)=>{
对于(int i=0;i
我不确定现在如何对外部列表进行排序

假设已对所有内部子列表进行排序,现在可以:

input = input.OrderBy(subList => String.Join(",", subList)).ToList();
这将子列表连接到单个字符串以进行比较,这样,如果第一个元素相同,它将比较列表的第二个元素。第三,如果第二个元素相同


在使用
String.Join()
时应该有一个分隔符,以避免在比较第一个元素时意外使用第二个元素。分隔符不应出现在原始字符串中。

您可以实现自己的列表比较器。不使用Linq

private static void Main()
{
    List<List<string>> list = new List<List<string>>
    {
        new List<string> {"fat", "twat", "gat"},
        new List<string> {"cat", "hat", "bat"},
        new List<string> {"twat", "lack", "rat"}
    };

    // sort the inner list
    foreach (var l in list)
    {
        l.Sort();
    }

    list.Sort(new ListComparer<string>()); // sort outer list according to ListComparer class.
}
private static void Main()
{
列表=新列表
{
新列表{“fat”、“twat”、“gat”},
新名单{“猫”、“帽子”、“蝙蝠”},
新列表{“twat”、“lack”、“rat”}
};
//对内部列表进行排序
foreach(列表中的变量l)
{
l、 排序();
}
Sort(new ListComparer());//根据ListComparer类对外部列表进行排序。
}
这是列表比较器

class ListComparer<T> : Comparer<List<T>> where T : IComparable
{
    // Compare lists elements until they are no more equal.
    // return result of last compared elements as result.
    public override int Compare(List<T> x, List<T> y)
    {
        int compared = 0;
        for (int i = 0; compared == 0 && i < x.Count && i < y.Count ; i++)
        {
            compared = x[i].CompareTo(y[i]);
        }
        return compared;
    }
}
类ListComparer:比较器,其中T:IComparable
{
//比较列表元素,直到它们不再相等。
//返回最后比较的元素的结果作为结果。
公共覆盖整数比较(列表x、列表y)
{
int=0;
对于(int i=0;比较==0&&i
方法
Compare
返回一个整数,该整数指示第一个列表是更大(
1
)还是第二个列表(
-1
)。如果两个列表相等,它将返回
0


Sort
方法使用此结果对列表进行排序。

由于
sortList
的签名具有返回类型,因此最好不要修改
输入
列表的内容-这可能只会导致副作用和错误代码

以下是我将如何解决这个问题:

public static List<List<String>> sortList(List<List<String>> input)
{
    return input
        .Select(x => x.OrderBy(y => y).ToList())
        .OrderBy(x => String.Join(", ", x))
        .ToList();
}
公共静态列表排序列表(列表输入)
{
返回输入
.Select(x=>x.OrderBy(y=>y).ToList())
.OrderBy(x=>String.Join(“,”,x))
.ToList();
}
因此,考虑到这一输入:

var input = new List<List<string>>()
{
    new List<string>() { "fat", "twat", "gat", },
    new List<string>() { "cat", "hat", "bat", },
    new List<string>() { "twat", "lack", "rat", },
};
var输入=新列表()
{
新列表(){“fat”、“twat”、“gat”,},
新列表(){“猫”、“帽子”、“蝙蝠”,},
新列表(),
};
这将是输出:


我只是想知道,如果我在
input
上执行
Sort()
,会有什么效果。i、 e,
input.Sort()
?@Zeeshan:如果您直接在列表上调用Sort而不使用任何参数,它将尝试使用默认比较器来比较列表和列表。但默认情况下没有,因此会出现编译错误。为了调用List上的Sort(),您需要告诉编译器如何比较List类型的两个元素,方法是为Sort()提供lambda表达式或自定义比较器,如果第一个元素相等,第二个元素如何?@M.kazemAkhgary好的一点,我并没有真正考虑到这一点。我用我想到的另一个解决方案修改了我的答案,如果可以的话,请随意建议一个更好的解决方案have@M.kazemAkhgary说得好。我对此提出了一个答案。这并不是先对内部列表排序。@Enigmativity我会编辑以澄清它,因为OP只是要求对外部列表进行排序。OP要求根据排序后的内部列表中的值对外部列表进行排序。我想使用string.Join()在OrderBy()中生成用于比较的键可能会造成不想要的效果。例如,在比较“twat”和“twa”时,它会将第一个元素的最后一个“t”与“,”character@PhuongNguyen-最好有一个分割字符,而不是没有。如果这两个字符串是
“ba”、“ram”
而不是
“bar”、“am”
,该怎么办?我认为从OP的例子中选择
“,”
分隔符是一个公平的选择,但它也可以是
“|”
。您可以使用
排序。OrderBy(x=>String.Join(“,”,“[“+x+”])
来消除包含元素的所有影响,如
“bar”,
@M.kazemAkhgary-您指的是哪种黑客?