C# 删除列表中的所有内容似乎不起作用c

C# 删除列表中的所有内容似乎不起作用c,c#,C#,我有一个相当简单的问题。我有一个不同长度的字符串列表,问题是根据按降序排序的字符串长度输出字符串。。i、 e从最长到最小 这就是我正在尝试的,但不确定我会错在哪里 namespace SortList { class Program { static void Main(string[] args) { List<string> strings = new List<string>() { "123

我有一个相当简单的问题。我有一个不同长度的字符串列表,问题是根据按降序排序的字符串长度输出字符串。。i、 e从最长到最小

这就是我正在尝试的,但不确定我会错在哪里

namespace SortList
{

    class Program
    {
        static void Main(string[] args)
        {
            List<string> strings = new List<string>() { "12345678", "1", "12", "123456789", "123", "1234", "12345", "123456", "654321" };
            PrintWordss(strings);
        }



    private static void PrintWords(List<string> words)
    {
        var sortedWords = words.OrderByDescending(word => word.Length).ToList();
        foreach (var word in sortedWords)
        {
            if (DoSomeLogic(word))
            {
                Console.WriteLine(word + " and its lenght is = " + word.Length);
                sortedWords.RemoveAll(w => w.Length == word.Length);
            }
        }
    }

    private static bool DoSomeLogic(string word)
    {
        // Some complicated logic here which is not relevant to the problem.
        // Assuming this returns true.
        return true;
    }

    }

}
但我想看到的是

123456789 and its lenght is = 9
12345678 and its lenght is = 8
123456 and its lenght is = 6
12345 and its lenght is = 5
1234 and its lenght is = 4
123 and its lenght is = 3
12 and its lenght is = 2
1 and its lenght is = 1
我想看看654321哪个长度为6的要从列表中删除


如何在列表中循环执行此操作?

除了按字符串长度排序外,还需要按字符串长度分组,然后从每组中选择第一项。这样就无需修改正在迭代的集合

改用这个:

private static void PrintWordss(List<string> words)
{
    var sortedWords = words.OrderByDescending(word => word.Length)
                           .GroupBy(word => word.Length)
                           .Select(word => word.First())
                           .ToList();

    foreach (var word in sortedWords)
        Console.WriteLine("{0} and its length is = {1}", word, word.Length);
}
由于OrderByDescending将123456放在654321之前,因此在分配给SortedWord之前,将从结果中删除654321

使用您的数据进行了测试,得到了所需的输出。

您正在对sortedWords.ToList进行枚举,这类似于说:

var newList = sortedWords.ToList();
foreach(var newString in newList)
{
    // ...
}
从原始SortedWord列表中删除时,新列表仍包含所有元素。一个快速修复方法是将枚举更改为循环SortedWord本身,不幸的是,这意味着您将在枚举时更改枚举,这在C中是不允许的

更简洁的方法可能是创建一个分组,并且只打印组中的一个成员:

foreach (var group in sortedWords.GroupBy(x => x.Length))
{
    foreach(var word in group)
    {        
        if(SatisfiesRulesAndConditions(word))
        {
            Console.WriteLine(word  + " and its length is = " + word.Length);
            break;
        }
    }
}

按长度排序,然后将它们分组在一起,这样您就可以只获取不同的via FIRSTOOFDEFAULT长度。接下来可以做的事情是将它们从源集合中删除,而不是从正在迭代的集合中删除。如果无法访问原始项或不想访问原始项,则创建一个包含这些项的本地范围的集合,并从中删除它们

static void Main(string[] args)
{
    List<string> strings = new List<string>() { "12345678", "1", "12", "123456789", "123", "1234", "12345", "123456", "654321" };
    PrintWordss(strings);
    Console.WriteLine(strings.Count + " strings remain.");
}

private static bool SatisfiesRulesAndConditions(string word)
{
    return true;
}

private static void PrintWordss(List<string> words)
{
    var sortedWords = words.OrderByDescending(word => word.Length)
                               .GroupBy(word => word.Length)
                               .Select(word => word.First())
                               .ToList();

    foreach (var word in sortedWords)
    {
        Console.WriteLine(word + " and its lenght is = " + word.Length);

        if (SatisfiesRulesAndConditions(word))
        {
            words.RemoveAll(w => w.Length == word.Length);
        }
    }
}
由于我的SatisfiesRulesAndConditions方法总是返回true,因此在循环的最后,集合中将没有剩余项。请注意,由于List words是对原始List strings集合的引用,因此从words参数中删除它们也将从原始集合中删除它们。如果您不想这样做,那么创建一个本地范围的字段,可以像这样为您保存它们的副本

private static void PrintWordss(List<string> words)
{
    var sortedWords = words.OrderByDescending(word => word.Length)
                               .GroupBy(word => word.Length)
                               .Select(word => word.First())
                               .ToList();

    // Clone list so original isn't modified.
    var copyofWords = words.Select(item => (string)item.Clone()).ToList();

    foreach (var word in sortedWords)
    {
        Console.WriteLine(word + " and its lenght is = " + word.Length);

        if (SatisfiesRulesAndConditions(word))
        {
            copyofWords.RemoveAll(w => w.Length == word.Length);
        }
    }
}

希望这有帮助。

您的问题不清楚。什么标准决定了应该从列表中排除什么?基本上,如果列表中有相同长度的字符串,则只应打印其中一个字符串。如果这样做,我会得到以下异常集合被修改;枚举操作不能为回复名称执行枚举。但我只是简化了我想要完成的逻辑。让我试着解释一下,列表中的每个字符串都受到一组特定规则和条件的约束,一旦满足了这些规则,就需要从列表中删除该字符串以及所有长度相同的字符串。因此程序会拾取一个比删除的字符串短的字符串。有什么方法可以使用foreach语句来完成此任务吗?@user3375390经过编辑以反映需要检查组中的每个单词。NominSim,我刚刚更新了原始版本。感谢您的回复,但正如我说过的,即使在调用DoSomeLogicstring方法之前,我也不想按长度对字符串列表进行分组,正如我最近编辑的问题中所指出的那样。在列表中循环时,我是否可以完成此任务?@user3375390此代码仍然可以执行与您所述相同的逻辑。感谢您的回复许可。但我只是简化了我想要完成的逻辑。让我试着解释一下,列表中的每个字符串都受到一组特定规则和条件的约束,一旦满足了这些规则,就需要从列表中删除该字符串以及所有长度相同的字符串。因此程序会拾取一个比删除的字符串短的字符串。我希望那些对答案投反对票的人能解释一下为什么这样海报可以学到一些东西。我不知道为什么是dv。这似乎是个好答案。就我个人而言,我不确定OP到底在寻找什么,也不确定我们的任何答案是否是他想要的。
123456789 and its lenght is = 9
12345678 and its lenght is = 8
123456 and its lenght is = 6
12345 and its lenght is = 5
1234 and its lenght is = 4
123 and its lenght is = 3
12 and its lenght is = 2
1 and its lenght is = 1
0 strings remain.
private static void PrintWordss(List<string> words)
{
    var sortedWords = words.OrderByDescending(word => word.Length)
                               .GroupBy(word => word.Length)
                               .Select(word => word.First())
                               .ToList();

    // Clone list so original isn't modified.
    var copyofWords = words.Select(item => (string)item.Clone()).ToList();

    foreach (var word in sortedWords)
    {
        Console.WriteLine(word + " and its lenght is = " + word.Length);

        if (SatisfiesRulesAndConditions(word))
        {
            copyofWords.RemoveAll(w => w.Length == word.Length);
        }
    }
}
123456789 and its lenght is = 9
12345678 and its lenght is = 8
123456 and its lenght is = 6
12345 and its lenght is = 5
1234 and its lenght is = 4
123 and its lenght is = 3
12 and its lenght is = 2
1 and its lenght is = 1
9 strings remain.