2013-02-23 4 views
1

Я создаю класс целочисленного набора, в котором объект может содержать до 101 номера через булевский массив. Мое задание - использовать петли foreach, когда это возможно, но я не могу найти место, где я могу его использовать /, где было бы даже разумно использовать его.Когда/Как заменить цикл for с помощью 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; 
} 
+0

Что такое 'set' ?? –

+0

'public bool [] set = new bool [101];' – krikara

+0

Не имеет прямого отношения к вашему вопросу, но ваш метод isEqual может быть более эффективным. Нет необходимости подсчитывать количество хороших совпадений - верните false, как только вы найдете неправильное совпадение. – siger

ответ

6

В общем, вы используете 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); 
} 
+0

dunno whats up with downvotes круглый здесь. Ваш пост на месте. – Quibblesome

+0

сохранять спокойствие ... это была просто какая-то дыра: D возьмите мой верхний! : D –

+0

Отличный ответ, именно это я и искал: можем ли мы также модифицировать коллекцию. – krikara

2

Простое эмпирическое правило, что может помочь вам:

Используйте для петель для массивов и петли foreach для итераторов

Все ваши коллекции, похоже, arra ys, поэтому ваше использование цикла (fors) является правильным.

1

Первый цикл не может быть заменен на foreach, так как невозможно изменить элементы в петле foreach.

Второй и третий для цикла - не очень хорошие кандидаты, потому что петли foreach проходят через один набор, но вам нужно, чтобы они проходили через оба набора.

Вы могли бы теоретически использовать Zip (доступный из .NET 4) или создать функцию, которая возвращает IEnumerable<Pair<int,int>>, где Pair это класс, который просто holds two values, а затем использовать эту функцию в обоих unionSet и isEqual. См. Это question, например, с KeyValuePair стоящим для воображаемого Pair. Это может быть то, о чем просит учитель, или это может быть излишним. Зависит от учителя.

+0

Ваш ответ на самом деле очень хороший, но я считаю, что первое сообщение вводит в заблуждение ... Уверен, что мой дом я могу заменить первым * для * * foreach *. –

1

Вы можете заменить каждый из них для петель с этой конструкцией:

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

Кроме того, заметьте, что любой bool[] table = new bool[10]; имеет все значения, установленные в false, как false это значение по умолчанию для типа BOOL.

+0

Это правда, что его можно было заменить, но это не было бы улучшением. Кроме того, foreach выглядит вроде глупо: D –

+0

Я думаю, что это глупо вообще, как мой учитель хочет, чтобы я сделал это, когда это просто кажется неуместным. – krikara

+0

@ krikara well Я думаю, у вас хороший учитель ... хорошо знать разницу между * для * и * foreach * –

Смежные вопросы