2

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

我想要做的是,如果 IEnumerable 中任何对象的问题的长度> 25,那么“子字符串”它并添加“...”

所以我的想法是这样的:

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

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

有没有办法做到这一点?..我真的不想为此创建一个循环..因为我根本不喜欢循环:)

提前致谢!

4

2 回答 2

10

谨慎接近

您可以使用 LINQ 中著名的ForEach扩展方法来遍历每个项目并相应地对其进行操作。本质上它与您描述的方法相同Change,并且可能看起来像这样:

ForEachLINQ 扩展方法

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

论证和额外阅读

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

于 2012-06-11T09:37:30.120 回答
0

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

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

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, "...");
于 2012-06-11T09:55:54.383 回答