何时/如何用foreach替换for循环

本文关键字:替换 for 循环 foreach 何用 何时 | 更新日期: 2023-09-27 18:00:44

我正在创建一个整数集类,对象通过布尔数组最多可以容纳101个数字。我的任务是尽可能使用foreach循环,但我找不到一个可以使用它的地方/在哪里使用它甚至有意义。

以下是我的一些代码片段,我完全按照老师的要求完成了这个程序。如果可能的话,我甚至不能完全弄清楚并集到foreach循环中。这个程序可以通过foreach循环来改进吗?如果可以,在哪里?

public bool[] set = new bool[101];
public IntegerSet(){
    for (int k = 0; k < set.Length; k++)
    {
        set[k] = false;
    }
public IntegerSet unionSet  (IntegerSet a)
{
    IntegerSet c = new IntegerSet();
    for (int i = 0; i < 101; i++)
    {
        if (a.set[i] == true || this.set[i] == true)
            c.set[i] = true;
    }
    return c;
}
public bool isEqual(IntegerSet a)
{
    int count = 0;
    for (int i = 0; i < 101; i++)
    {
        if (a.set[i] == this.set[i])
            count++;
    }
    if (count == 101)
        return true;
    else
        return false;
}

何时/如何用foreach替换for循环

通常,当您处理单个集合而不修改它时,会使用foreach循环。在有多个集合的情况下,带有索引的循环更合适。

在您的情况下,三个循环都不符合上面的描述:

  • 第一个循环写入数组
  • 第二和第三循环处理多个序列

您可以稍微简化代码,但无论何时使用两个集合,for循环都更合适(我认为使用LINQ不是一种选择)。

public IntegerSet unionSet  (IntegerSet other) {
    IntegerSet res = new IntegerSet();
    for (int i = 0; i < 101; i++) {
        res.set[i] = other.set[i] || this.set[i];
    return res;
}
public bool isEqual(IntegerSet a) {
    for (int i = 0; i < 101; i++) {
    if (a.set[i] != this.set[i])
        return false;
    return true;
}

为了完整起见,有了LINQ,你可以避免大多数循环:

public IntegerSet unionSet(IntegerSet other) {
    // Assume that you have a constructor that takes IEnumerable<bool>
    new IntegerSet(set.Zip(other.set, (a, b) => a || b));
}
public bool isEqual(IntegerSet a) {
    return set.SequenceEqual(a.set);
}

可能对您有所帮助的简单经验法则:

用于数组的循环和迭代器的foreach循环

所有的集合似乎都是数组,所以循环使用(fors)是正确的。

First for循环不能用foreach替换,因为不可能更改foreach循环中的元素。

第二个和第三个for循环不是很好的候选者,因为foreach循环遍历一个集合,但您需要它们遍历两个集合。

理论上,您可以使用Zip(可从.NET 4获得)或创建一个返回IEnumerable<Pair<int,int>>的函数,其中Pair是一个只包含两个值的类,然后在unionSetisEqual中都使用此函数。例如,请参阅此问题,其中KeyValuePair代表想象中的Pair。这可能是老师的要求,也可能是小题大做。取决于老师。

您可以用以下构造替换每个for循环:

int counter = 0;
foreach(bool b in set)
{
   set[counter] = true;
   counter++;
}

另外,请注意,任何bool[] table = new bool[10];都将所有值设置为false,因为false是bool类型的默认值。