在列表上使用带有foreach Action的条件lambda语句

时间:2009-03-24 10:57:28

标签: c# lambda

为什么我不能这样做?

如果我有List<String> myList填充了项目,我希望能够以条件方式对每个成员采取行动:

myList.ForEach(a => { if (a.Trim().Length == 0) a = "0.0"; })

但这不会编译。我猜它与缺少一个返回值有什么关系?

我正在尝试准备转换为双打的字符串列表,我希望空项目显示为“0.0”,这样我就可以一次性转换整个列表。

3 个答案:

答案 0 :(得分:6)

ForEach不可变,它不会以任何方式改变数据结构。

你可以:

  1. 使用索引
  2. 自行处理循环
  3. 使用.Select和.ToList(假设您使用的是.NET 3.5)生成新列表
  4. #1的例子:

    for (Int32 index = 0; index < myList.Count; index++)
        if (myList[index].Trim().Length == 0)
            myList[index] = "0.0";
    

    使用.NET 3.5和Linq:

    myList = (from a in myList
              select (a.Trim().Length == 0) ? "0.0" : a).ToList();
    

    使用.NET 3.5,不使用Linq语法,而是使用Linq代码:

    myList = myList.Select(a => (a.Trim().Length == 0) ? "0.0" : a).ToList();
    

    编辑:如果您想要制作新的双打列表,您也可以使用Linq一次性完成:

    List<Double> myDoubleList =
        (from a in myList
         select (a.Trim().Length == 0 ? "0" : a) into d
         select Double.Parse(d)).ToList();
    

    请注意,使用“0.0”而不是“0”依赖小数点作为句号。在我的系统上它不是,所以我用“0”替换它,但更合适的方法是将调用更改为Double.Parse以采用显式数字格式,如下所示:

    List<Double> myDoubleList =
        (from a in myList
         select (a.Trim().Length == 0 ? "0.0" : a) into d
         select Double.Parse(d, CultureInfo.InvariantCulture)).ToList();
    

答案 1 :(得分:4)

你可能想要的是:

public static void MutateEach(this IList<T> list, Func<T, T> mutator)
{
    int count = list.Count;
    for (int n = 0; n < count; n++)
        list[n] = mutator(list[n]);
}

允许:

myList.MutateEach(a => (a.Trim().Length == 0) ? "0.0" : a);

只需将MutateEach方法放在您自己的公共静态类中,并确保您有一个可以找到它的using指令。

是否值得定义这样的东西取决于你使用它的频率。请注意,它必须是IList上的扩展名,而不是IEnumerable,因此我们可以执行更新,这使其适用范围较小。

答案 2 :(得分:0)

@ daniel-earwicker的MutateEach扩展解决方案是一个很好的解决方案。


但是,为了返回一个新的List,您可以选择使用List.ConvertAll<TTo>(Converter<TFrom,TTo>(Func<TFrom, TTo>)),这是自.NET 2.0以来的一直存在。

不是 Linq ,或 Lambda

List<String> nodeStringList = new List<String>(new String[] { "", "0.5 ", " 1.1"}); 

nodeStringList = nodeStringList.ConvertAll<String>((c) => (c.Value.Trim().Length != 0) ? c.Value.Trim() : "0.0");

MSDN Reference - List.ConvertAll