从List中删除多余的项目时,枚举器陷入无限循环

3th*_*1ll 4 c# linq do-while

我有一个脚本,它接受一个int[]数组,将其转换为一个列表,并删除已经出现至少2次的所有进一步的整数.我遇到的问题是,当它进入我检查每个整数出现次数的循环时,我陷入了循环.

编辑:"我遗漏的是,列表必须保持其原始顺序,以便从上到下删除多余的数字.抱歉,如果那些已经回答的人感到困惑!

我认为改变的数量occursintegerOccurrence将作为while循环的计数变化.

关于我在这里缺少什么的想法?除了任何可辨别的技能.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;

public class Kata
{
    public static void Main()
    {
       int[] arr = new int[] {1, 2, 1, 4, 5, 1, 2, 2, 2};
        int occurrenceLimit = 2;
       var intList = arr.ToList();

        for (int i = 0; i < intList.Count; i++)
        {
            var occursintegerOccurrence = intList.Count(n => n == occurrenceLimit);

            do
            {
                occursintegerOccurrence = intList.Count(n => n == occurrenceLimit);
                foreach (var x in intList)
                {
                    Console.WriteLine(x);
                    intList.Remove(intList.LastIndexOf(occurrenceLimit));
                    // Tried changing the count here too
                    occursintegerOccurrence = intList.Count(n => n == occurrenceLimit);
                }
            } while (occursintegerOccurrence > occurrenceLimit);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Stu*_*tLC 5

这是一个相当简洁的版本,假设您要删除计数超过2的所有整数实例,将其余部分保留为原始序列,优先选择从左到右的保留:

int[] arr = new int[] {1, 2, 1, 4, 5, 1, 2, 2, 2};
var ints = arr.Select((n, idx) => new {n, idx})
               .GroupBy(x => x.n)
               .SelectMany(grp => grp.Take(2))
               .OrderBy(x => x.idx)
               .Select(x => x.n)
               .ToList();
Run Code Online (Sandbox Code Playgroud)

结果:

1,2,1,4,5,2

它的工作原理是使用索引重载Select来投射匿名元组并执行原始顺序以允许在最后重新排序.


Cir*_*ino 5

死循环的原因是线路

 intList.Remove(intList.LastIndexOf(occurrenceLimit));
Run Code Online (Sandbox Code Playgroud)

..您要删除的值等于occurrenceLimit值(= 2)列表中的最后一次出现,即“8”(数组的最后一个索引从 0 开始计数)。

由于列表中不存在“8”,因此您不会删除任何内容,循环持久性测试也不会更改,因此它始终经过验证并且循环永远不会结束。

这种方法适用于任何值,occurrenceLimit但我认为 StuartLC 的解决方案更好..

int[] arr = new int[] { 1, 2, 1, 4, 5, 1, 2, 2, 2 };
int?[] arr2 = new int?[arr.Length];
arr2.ToList().ForEach(i => i = null);
int occurrenceLimit = 2;

var ints = arr.GroupBy(x => x).Select(x => x.Key).ToList();

ints.ForEach(i => {
   int ndx = 0;
   for (int occ = 0; occ < occurrenceLimit; occ++){
        ndx = arr.ToList().IndexOf(i, ndx);
        if (ndx < 0) break;
        arr2[ndx++] = i;
   }
});

List<int?> intConverted = arr2.ToList();
intConverted.RemoveAll(i => i.Equals(null));
Run Code Online (Sandbox Code Playgroud)