为什么我不能这样做?
如果我有List<String> myList
填充了项目,我希望能够以条件方式对每个成员采取行动:
myList.ForEach(a => { if (a.Trim().Length == 0) a = "0.0"; })
但这不会编译。我猜它与缺少一个返回值有什么关系?
我正在尝试准备转换为双打的字符串列表,我希望空项目显示为“0.0”,这样我就可以一次性转换整个列表。
答案 0 :(得分:6)
ForEach不可变,它不会以任何方式改变数据结构。
你可以:
#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");