Update value of objects with lambda

I have this IEnumerable of type Question.. the class Question has the properties, Question(string) and Id(int)

What I want to do is if the question of any object in the IEnumerable has a length > 25 then "Substring" it and add "..."

So my idea was something like:

ienumQuestions.Where(e=>e.Question.Length > 25).Change(e.Question=>e.Question.Substring(25)+"...");

Now im not sure if that syntax was 100% correct but I hope you get the point..

Is there wanyway to do this?.. i really dont want to create a loop for this.. since I simply dont like loops :)

Thanks in advance!

Answers


Approach with caution

You could use the renowned ForEach extension method in LINQ to iterate through each item and action it accordingly. Essentially it's the same as the Change method you described, and could look something like this:

ForEach LINQ Extension Method
public static void ForEach<TSource>(this IEnumerable<TSource> source, Action<TSource> action)
{
    foreach(TSource item in source)
    {
        action(item);
    }
}
Implementation
ienumQuestions.Where(e => e.Question.Length > 25).ForEach(e =>
{
    e.Question = e.Question.Substring(0, 25) + "...";
});

// or
ienumQuestions.ForEach(e =>
{
    if (e.Question.Length > 25)
    {
        e.Question = e.Question.Substring(0, 25) + "...";
    }
});
Argument and Extra Reading

I personally dislike the approach of using the ForEach LINQ extension to directly update the objects, I prefer to use it for reference purposes only. I would strongly recommend reading "foreach vs ForEach" before adopting it though, as essentially it goes against the principal of LINQ in the sense that it directly modifies objects within the collection, which is what LINQ was not originally intended to do.


There is no Change extension in LINQ, both IEnumerable and String are immutable (to slightly different levels) so cannot be changed.

I guess you want a truncate extension somthing like this,

IEnumerable<string> Truncate<T>(
    this IEnumerable<T> source,
    Func<T, string> stringAccessor,
    int length,
    string suffix)
{
    var strings = source.Select(stringAccesor);
    return strings.Select(s =>
        {
            if (s.Length < length)
            {
                return s;
            }

            return string.Format(
                "{0}{1}",
                s.SubString(0, length),
                suffix)
        });
}

Which you could call like this

var truncatedQuestions = ienumQuestions.Truncate(q => q.Question, 25, "...");

Need Your Help

MYSQL Trigger insert or update different table

mysql triggers where insert-update

I've been wrapping my head around this SQL statement I'm trying to make and I've reached a wall so to speak, if you could lend any advise as to what I am doing wrong that would be a big help. I get...

ImportError: No module named mysite.wsgi message when deploying heroku app

heroku gunicorn django-wsgi

-Mac OSX 10.7.5 -Python 2.7 -PostgreSQL 9.3.2 (set up via Heroku) -Django 1.6