在列表上使用条件 lambda 语句和 foreach 操作

发布于 2024-07-16 11:40:09 字数 304 浏览 2 评论 0原文

为什么我不能做这样的事情?

如果我有一个 List; myList 填充了项目,我希望能够以有条件的方式对每个成员进行操作,如下所示:

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

但这不会编译。 我猜这与缺少返回值有关?

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

Why Cant I do something like this?

If I have a List<String> myList populated with items, I want to be able to act on each member in a conditional way like so:

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

But this will not compile. Im guessing its something to do with missing a return value?

Im trying to prepare a list of strings for conversion to doubles, and I want the empty items to show '0.0' so I can just convert the whole list in one go.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凉城已无爱 2024-07-23 11:40:09

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

您可以:

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

#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();

ForEach is not mutable, it doesn't change the data structure in any way.

You can either:

  1. Handle the loop yourself, with an index
  2. Produce a new list, using .Select and .ToList (provided you're using .NET 3.5)

Example of #1:

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

With .NET 3.5 and Linq:

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

With .NET 3.5, not using the Linq-syntax, but using the Linq-code:

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

Edit: If you want to produce a new list of doubles, you can also do that in one go using Linq:

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

Note that using "0.0" instead of just "0" relies on the decimal point being the full stop character. On my system it isn't, so I replaced it with just "0", but a more appropriate way would be to change the call to Double.Parse to take an explicit numeric formatting, like this:

List<Double> myDoubleList =
    (from a in myList
     select (a.Trim().Length == 0 ? "0.0" : a) into d
     select Double.Parse(d, CultureInfo.InvariantCulture)).ToList();
若水微香 2024-07-23 11:40:09

您可能想要的是:

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,这样我们才能执行更新,这使得它的应用范围不太广。

What you possibly want is:

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

Which would allow:

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

Just put the MutateEach method in a public static class of your own and make sure you have a using directive that will find it.

Whether it's worth defining something like this depends on how often you'd use it. Note that it has to be an extension on IList instead of IEnumerable, so we can perform the updates, which makes it less widely applicable.

奈何桥上唱咆哮 2024-07-23 11:40:09

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


不过,要返回新的 List,您可以选择使用 List.ConvertAll(Converter(Func)) ,自 .NET 2.0 以来一直存在。

它不是 LinqLambda

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 参考 - List.ConvertAll

@daniel-earwicker's MutateEach Extension solution is a good solution.


Though, for returning a new List, you have the option to use List.ConvertAll<TTo>(Converter<TFrom,TTo>(Func<TFrom, TTo>)), which has been around since .NET 2.0.

It is not Linq, or 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文