2

Is it possible to modify elements of a collection, say List, LinkedList, etc using something like:

collection.Do ( action )

which does something like:

item.Value = 0
(for each item)

I know enumerators only give the value, not the reference, hence the question.

How would one do this using LINQ?

2 Answers 2

6

Try:

void ModifyEach<T>(this IList<T> list, Func<T, T> modifier)
{
    for (int n = 0; n < list.Count; n++)
        list[n] = modifier(list[n]);
}

Usage:

List<int> x = new List<int> { 1, 3, 7 };

x.ModifyEach(n => n + 1); // increment each item
Sign up to request clarification or add additional context in comments.

6 Comments

Not unless you use IEnumerable.ElementAt(), because by default IEnumerable doesn't provide random access. You can't use foreach because that would modify the collection.
No, it can only work with a collection interface that allows you to modify the contents of the list at a specific position, which basically means IList or IDictionary.
@Andy, ElementAt is no use; what's needed is the ability to modify the collection, not random access (I'm only using the [int] indexer to allow modification).
Couldn't you just do x = x.Select(n => n + 1).ToList(); ?
@Cameron, That would create a new list rather than doing an in-place modification of the existing list.
|
2

If your collection contains reference types then you can modify its items in-place by using an extension method, similar to the ForEach method on List<T>.

This is possible because you're not actually trying to alter the IEnumerable<T> sequence: The collection contains references but you're only modifying the referenced objects, not the references themselves.

This technique won't work for collections of value types. In that case you would be trying to alter the read-only, IEnumerable<T> sequence, which isn't possible.

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (T item in source)
    {
        action(item);
    }
}

// ...

public class Example
{
    public int Value { get; set; }
}

// ...

Example[] examples =
    {
        new Example { Value = 1 }, new Example { Value = 2 },
        new Example { Value = 3 }, new Example { Value = 4 }
    };

examples.ForEach(x => x.Value *= 2);

// displays 2, 4, 6, 8
foreach (Example e in examples)
{
    Console.WriteLine(e.Value);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.