使用 lambda 更新对象的值

本文关键字:对象 更新 lambda 使用 | 更新日期: 2023-09-27 18:36:42

我有这个 IEnumerable 的类型 Question.. 类 Question 具有属性,Question(string) 和 Id(int)

我想做的是,如果 IEnumerable 中任何对象的问题的长度> 25然后"子字符串"它并添加"..."

所以我的想法是这样的:

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

现在我不确定该语法是否 100% 正确,但我希望你明白这一点。

有什么办法吗?..我真的不想为此创建一个循环......因为我根本不喜欢循环:)

提前感谢!

使用 lambda 更新对象的值

谨慎处理

可以使用 LINQ 中著名的ForEach扩展方法来循环访问每个项并相应地执行操作。本质上,它与您描述的Change方法相同,可能如下所示:

ForEach LINQ 扩展方法

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

实现

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) + "...";
    }
});

论证和额外阅读

我个人不喜欢使用 ForEach LINQ 扩展直接更新对象的方法,我更喜欢将其仅用于参考目的。不过,我强烈建议在采用它之前阅读"foreach vs ForEach",因为它本质上违背了 LINQ 的原则,因为它直接修改集合中的对象,而这正是 LINQ 最初不打算做的。

LINQ 中没有Change扩展,IEnumerableString 都是不可变的(级别略有不同),因此无法更改。

我猜你想要一个这样的截断扩展,

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)
        });
}

你可以这样称呼

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