Domanda

I'm trying to use the Array.ForEach() extension method to loop through for a list of filtered elements from an array and then modify those values, unfortunately that doesn't seem to work I'm guessing because it doesn't actually modify the reference value of each element.

Is there any way to do this besides storing the results of the Array.ForEach() into a seperate array and then cloning that array to the original array? Also I know I could obviously do all of this without cloning if I use a for loop but if I could do it this way it would be cleaner and would be less code.

Here's the snippet:

Array.ForEach(Array.FindAll(starts, e => e < 0), e => e = 0);
È stato utile?

Soluzione

ForEach simply isn't intended to do this - just like you wouldn't be able to do this with a foreach loop.

Personally I'd just use a for loop - it's easy to read and clear:

for (int i = 0; i < array.Length; i++)
{
    // Alternatively, use Math.Max to pull up any negative values to 0
    if (array[i] < 0)
    {
        array[i] = 0;
    }
}

It really is simple - anyone will be able to understand it.

Now you could write your own extension method instead. You could write one to replace all values which satisfy a predicate with a fixed value, or you could write one to replace all values entirely... but I don't think it's really worth it. As an example of the latter:

public static void ReplaceElements<T>(this T[] array,
                                      Func<T, T> replacementFunction)
{
    // TODO: Argument validation
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = replacementFunction(array[i]);
    }
}

Then call it with:

starts.ReplaceElements(x => Math.Max(x, 0));

I'd personally still use the for loop though.

(You could potentially change the above very slightly to make it take IList<T> and use Count instead. That would still work with arrays, but also List<T> etc too.)

Altri suggerimenti

You can do that with ref and delegates. However, I don't think it adds much value.

public delegate void RefAction<T>(ref T value);
public static void ForEachRef<T>(this T[] array, RefAction<T> action)
{
    for (int i = 0; i < array.Length; ++i) action(ref array[i]);
}

You can use it as follows:

var myArray = new int[];
myArray.ForEachRef((ref int i) => i = whateverYouLike());

From the standpoint of possibility, there could be an interface IRefEnumerable<T> which iterates some container with assignable elements.

array = array.Select(x => (x < 0) ? 0: x).ToArray();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top