首页 > 解决方案 > 当 List 不为空时,从 List 中删除一个随机元素会导致无限循环

问题描述

我正在研究一个简单的随机播放脚本。我有一个通用方法,它将 a 作为输入List<T>并返回 a List<T>。返回的List应该是洗牌的。但是,代码陷入了无限循环,我不知道为什么

这是我的代码:

private List<T> Shuffle<T>(List<T> p)
{
    List<T> result = new List<T>();
    int idx = 0;

    while (p.Count > 0)
    {
        idx = Random.Range(0, p.Count);

        print(idx);
        result.Add(p[idx]);
        p.Remove(p[idx]);
    }

    print("Shuffled");
    return result;
}

我希望代码能够工作,因为p.Count 越来越小。但是,它卡住了。while这是我制作的循环的替代方法,它有效,但感觉有些草率:

for (int i = 0; i < p.Count; i++)
{
    idx = Random.Range(0, p.Count);
    print(idx);

    result.Add(p[idx]);
    p.Remove(p[idx]);
}

这更像是一个“为什么”的问题而不是一个问题,但我仍然希望你能帮助我。提前致谢!

标签: c#listloopsgenericsshuffle

解决方案


第一行

List<T> result = p;

问题。请注意,这resultp共享相同的参考,这就是为什么

result.Add(p[idx]);

添加 toresult和 top p.Count > 0 永远成立while (p.Count > 0)(变成无限循环。应该

private List<T> Shuffle<T>(List<T> p)
{
    List<T> result = new List<T>(); // result and p are different lists now

    while (p.Count > 0)
    {
        idx = Random.Range(0, p.Count);

        print(idx);
        result.Add(p[idx]);  // Now we Add to result only, and Remove from p
        p.RemoveAt(idx);     // <- I suggest removing at index
    }

    print("Shuffled");
    return result;
}

推荐阅读