1

It's easy to fill up an array using for loop:

ulong[] chessArray = new ulong[64];
chessArray[0] = 1;
for (int i = 1; i < 64; i++)
{
    chessArray[i] = 2 * chessArray[i - 1];
}

But is there a way to do it using foreach operator? The following code won't compile:

ulong[] chessArray = new ulong[64];
chessArray[0] = 1;
foreach (int element in chessArray)
{
    element = 2 * (element - 1);
}
Evgeny Kremer
  • 23
  • 1
  • 4
  • 4
    you cannot update the same array which you are iterating using foreach – Mostafiz Jan 12 '17 at 10:45
  • 5
    why do you want that? you already know how to solve the problem using `for` – slawekwin Jan 12 '17 at 10:47
  • It's even possible to do this in one line `chessArray = chessArray.Select(elem => 2 * (elem - 1)).ToArray())` But the question is why? – mrogal.ski Jan 12 '17 at 10:50
  • There was some discussion about enabling such a feature as part of the [`ref` returns and locals](https://github.com/dotnet/roslyn/issues/118) feature, but so far as I'm aware, nobody has provided a compelling use case where (unlike here) a simple workaround is not already available. – Damien_The_Unbeliever Jan 12 '17 at 10:51
  • 1
    @m.rogalski However, this will create a new array which may have side effects when the original array is used elsewhere. – wkl Jan 12 '17 at 10:51
  • 1
    Possible duplicate of [Changing objects value in foreach loop?](http://stackoverflow.com/questions/17676974/changing-objects-value-in-foreach-loop) – MakePeaceGreatAgain Jan 12 '17 at 10:52
  • 1
    @m.rogalski: The legend has it that the inventor of chess was given a free wish from the indian emperor as a reward for the invention. He wished that the emperor may put one grain of wheat on the first field, two on the second field, four on the third field, and so on, always doubling the number of grains for each field. Although looking easy at the beginning, the task proved to be impossible. I suppose the calculation/visualization of this might be the story behind the question. – Thern Jan 12 '17 at 11:04
  • you can generate the array: `ulong[] chessArray = Enumerable.Range(0, 64).Select(i => 1 << i).ToArray();` – Dmitry Bychenko Jan 12 '17 at 11:18

4 Answers4

2

is there a way to do it using foreach operator?

No. The loop variable element is a read-only variable that contains a copy of the value of the array element, which is a variable. It is not an alias to the array element variable.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
0

It is not possible to modify the array you are iterating using foreach, check this link : https://msdn.microsoft.com/en-us/library/ttw7t8t6.aspx

Ali Ezzat Odeh
  • 2,093
  • 1
  • 17
  • 17
0

Why foreach? Your goal is to fill an array, in which each element's value is based on previous one. Clojure natively support such sequence creation by iterate.

(take 10 (iterate (partial * 2) 1)) //(1 2 4 8 16 32 64 128 256 512)

Notice the integer overflow if you want to take 64.

The same idea can apply to C#. (Please tell me if there is already an Iterate function).

public static IEnumerable<T> Iterate<T>(Func<T, T> f, T seed)
{
    var val = seed;
    while (true)
    {
        yield return val;
        val = f(val);
    }
}

Then you can fill an array by

Iterate(i => i * 2, (ulong)1).Take(64).ToArray()
qxg
  • 6,955
  • 1
  • 28
  • 36
0

The other answers and comments already show nicely that you cannot write to the loop variable in a foreach loop. However, even if this was possible, the two loops in the question would not do the same thing:

You cannot access the previous value of the loop variable by element - 1! Instead this will simply subtract one from the current variable before it is doubled. The result is completely independent of the previous value.

I.e. your foreach loop would correspond to 2 * chessArray[i] - 1; in the for loop.

wkl
  • 1,896
  • 2
  • 15
  • 26