views:

463

answers:

6

We know that if you have:

var aa = new [] { 1, 2, 3, 4, 5 };
for (int i = 0; i < aa.length; ++i)
{
    aa[i] = aa[i] + 1;
}

it's really

var aa = new [] { 1, 2, 3, 4, 5 };
Arrary.ForEach(aa, a => a + 1);

However, what if I had this:

var aa = new [] { 1, 2, 3, 4, 5 };
var ab = new [] { 1, 2, 3, 4, 5 };
for (int i = 0; i < aa.length; ++i)
{
    aa[i] = ab[i] + 1;
}

Can I convert this to use just one Array.ForEach? Or, how would you do it, if you wanna go all functional programming crazy? Clunky for loops just looks ugly.

+1  A: 

This won't be fast, but it just might work

var aa = new [] { 1, 2, 3, 4, 5 };
var ab = new [] { 1, 2, 3, 4, 5 };
Array.ForEach(aa, new Action(a => ab[Array.IndexOf(a)] + 1));

Unfortunately thiswill not work for an array with duplicate elements.

Jon Limjap
Why won't it be fast?
Hao Wooi Lim
Because Array.IndexOf is an O(n) operation inside a ForEach which is an O(n) operation as well.
Jon Limjap
+2  A: 

It's not pretty, but this will work (using the Select() overload that returns the index of the element):

var aa = new[] { 1, 2, 3, 4, 5 };
var ab = new[] { 1, 2, 3, 4, 5 };

Array.ForEach(
    aa.Select((x, i) => i).ToArray(),
    i => aa[i] = ab[i] + 1);

IMHO a simple "for" loops is a lot easier to understand in this case.

Matt Hamilton
I can't seems to find the Select overload, is this part of Linq, or is a custom written method?
Hao Wooi Lim
Yeah just part of Linq. Select can take a function which passes the index (an int) as the second parameter.
Matt Hamilton
+2  A: 

Another similar approach:

Enumerable.Range(0, ab.Length).Select(i => aa[i] = ab[i] + 1);
// Will not work if aa.Length != ab.Length
CMS
+4  A: 

How about:

aa = ab.ConvertAll(x => x+1);
Jon Skeet
Ah heck there's plenty of ways to do it if you're just gonna reassgn aa! I figured he wanted to do it in place.
Matt Hamilton
Yeah, doing it with a destination array is "interesting". It might be fun to add an extension method which is like ConvertAll but which takes an existing destination array.
Jon Skeet
Good answer btw. But actually I simply made up a toy problem (Not the real one I was trying to solve) where I'm in a situation where I needed the index to refer to a few other arrays. But Thanks anyway :)
Hao Wooi Lim
Do you actually need the index, or do you just need to get a slice into all the other arrays at the same place? If it's the latter, see http://stackoverflow.com/questions/496704
Jon Skeet
Great, I got just what I wanted in your first question of that link.
Hao Wooi Lim
A: 

Not a direct answer, but you want ForEach2, which iterates over two sequences/arrays. Unfortunately this is not included with the BCL, so you'll have to add it.

But if you're trying to do functional in C#, you'll probably have a helper library anyways, so it's not that big of a deal.

MichaelGG
A: 
var aa = new[] { 1, 2, 3, 4, 5 };
var ab = new[] { 1, 2, 3, 4, 5 };

var index = 0;
Array.ForEach(aa, a => { aa[index] = ab[index] + 1; index++; });

Would this not work? Its 1 Array.ForEach with the indexer held outside of the Array.ForEach.