何时从0循环到结束以及何时从结束循环到0?

时间:2015-05-14 02:16:38

标签: c# for-loop

从0循环到列表末尾(列表或映射)以及从结尾循环到0的场景是什么?下面是代码片段,它从0到最后遍历列表以过滤掉某些特定的学生姓名。此代码是否会在任何情况下抛出任何异常?从列表末尾迭代到零会对此代码产生任何影响吗?

List<Dictionary<string, string>> allStudentsList = allStudentsArray.ToList();
for (int i = 0; i < allStudentsList .Count-1; i++) {
    Dictionary<string, string> student= allStudentsList .ElementAt(i);
    string studentName;
    bool hasValue = studentName.TryGetValue("id", out studentName);
    if (hasValue) {
        if (studentName.StartsWith("John") {
            allStudentsList.RemoveAt(i);
            i--;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

首先,您的问题包含语义错误。它是:

  

end-10

如果您从end开始,由于ArgumentOutOfRangeException方法规范,您将立即获得ElementAt

如果您从从右向左移动,则在i++为真的情况下,您不必执行增量(hasValue)。仅仅因为索引左侧的项目没有移动。所以你可以实现它:

List<Dictionary<string, string>> allStudentsList = allStudentsArray.ToList();
for (int i = allStudentsList.Count-1; i >= 0; i--) {
    Dictionary<string, string> student = allStudentsList.ElementAt(i);
    string studentName;
    bool hasValue = studentName.TryGetValue("id", out studentName);
    if (hasValue) {
        if (studentName.StartsWith("John") {
            allStudentsList.RemoveAt(i);
        }
    }
}

接下来,它可以改善性能。如果从List<T>.RemoveAt中删除元素,则表示索引右侧的所有元素都放在左侧的一个位置。现在,如果你先从右边删除,右边的项目数量会很少,而且如果索引位于零附近,那么要向左移动的项目数量会更小(仅仅因为某些元素已经存在)去除)。但是,如果hasValue很少true,那么不要期望获得巨大的性能提升。

在这种情况下,for是向前还是向后完成并不重要,因为有共享状态&#34;在不同的迭代中。

答案 1 :(得分:1)

现在,我想提供一个伴侣答案,以回应CommuSoft最优秀,最彻底的事先评论。 (即&#34;没有关系,&#34;而是:&#34;并行... tangental ...&#39; FYI&#39; ...&#34;) *

一般(和无论使用的语言是什么(!) ...),如果你通过任何某种数据结构,你删除的东西,总是想要从终点到0迭代#34;&#34; (否则,它确实无关紧要......)

为什么呢?因为,任何时候你从任何类型的集合中删除任何东西,&#39;长度&#39;该集合的减少量为1. 如果你正在从后向前迭代,这不是一个问题:你永远不会错过任何东西,&#34;你也不会两次遇到相同的元素。&#34;如果你正在以另一种方式旅行,那么(!)都非常真实(因此,#34;完全可以避免&#34;)。