【问题标题】:Convert existing snippet of code to use Array.ForEach将现有的代码片段转换为使用 Array.ForEach
【发布时间】:2009-01-28 03:49:10
【问题描述】:

我们知道,如果您有:

var aa = new [] { 1, 2, 3, 4, 5 };
for (int i = 0; i < aa.length; ++i)
{
    aa[i] = aa[i] + 1;
}

真的

var aa = new [] { 1, 2, 3, 4, 5 };
Arrary.ForEach(aa, a => a + 1);

但是,如果我有这个怎么办:

var aa = new [] { 1, 2, 3, 4, 5 };
var ab = new [] { 1, 2, 3, 4, 5 };
for (int i = 0; i < aa.length; ++i)
{
    aa[i] = ab[i] + 1;
}

我可以将其转换为仅使用一个 Array.ForEach 吗?或者,如果你想让所有的函数式编程变得疯狂,你会怎么做?笨重的 for 循环看起来很丑。

【问题讨论】:

  • 我无法编译您的第一个 ForEach 代码。 “new Action(a => a + 1)”没有意义,因为“a => a + 1”是一个Action,而“a + 1”不是一个语句。
  • 对不起,我现在在工作,所以我不在 .Net framework 3.5 上。我确实知道使用委托会起作用,但我不确定是否可以将其更改为使用 lambda 表达式...
  • “或者,如果你想让所有的函数式编程变得疯狂,你会怎么做?” -- 使用 F# :)

标签: c# c#-3.0 functional-programming lambda


【解决方案1】:

怎么样:

aa = ab.ConvertAll(x => x+1);

【讨论】:

  • 哎呀,如果您只是要重新分配 aa,那么有很多方法可以做到这一点!我想他想就地做这件事。
  • 是的,用目标数组来做是“有趣的”。添加一个类似于 ConvertAll 但采用现有目标数组的扩展方法可能会很有趣。
  • 顺便说一句,答案很好。但实际上我只是编造了一个玩具问题(不是我试图解决的真正问题),我处于需要索引来引用其他一些数组的情况。不过还是谢谢:)
  • 你真的需要索引,还是只需要在同一个地方对所有其他数组进行切片?如果是后者,请参阅stackoverflow.com/questions/496704
  • 太好了,我在您对该链接的第一个问题中得到了我想要的。
【解决方案2】:

这不是很漂亮,但这会起作用(使用返回元素索引的 Select() 重载):

var aa = new[] { 1, 2, 3, 4, 5 };
var ab = new[] { 1, 2, 3, 4, 5 };

Array.ForEach(
    aa.Select((x, i) => i).ToArray(),
    i => aa[i] = ab[i] + 1);

恕我直言,在这种情况下,一个简单的“for”循环更容易理解。

【讨论】:

  • 我好像找不到Select重载,这是Linq的一部分,还是自定义写的方法?
  • 是的,只是 Linq 的一部分。 Select 可以采用将索引(一个 int)作为第二个参数传递的函数。
【解决方案3】:

另一种类似的方法:

Enumerable.Range(0, ab.Length).Select(i => aa[i] = ab[i] + 1);
// Will not work if aa.Length != ab.Length

【讨论】:

    【解决方案4】:

    这不会很快,但它可能会起作用

    var aa = new [] { 1, 2, 3, 4, 5 };
    var ab = new [] { 1, 2, 3, 4, 5 };
    Array.ForEach(aa, new Action(a => ab[Array.IndexOf(a)] + 1));
    

    很遗憾,这不适用于具有重复元素的数组。

    【讨论】:

    • 因为 Array.IndexOf 是 ForEach 中的 O(n) 操作,它也是 O(n) 操作。
    【解决方案5】:
    var aa = new[] { 1, 2, 3, 4, 5 };
    var ab = new[] { 1, 2, 3, 4, 5 };
    
    var index = 0;
    Array.ForEach(aa, a => { aa[index] = ab[index] + 1; index++; });
    

    这不行吗?它的 1 个 Array.ForEach 与索引器保持在 Array.ForEach 之外。

    【讨论】:

      【解决方案6】:

      不是直接的答案,但您需要 ForEach2,它迭代两个序列/数组。不幸的是,这不包含在 BCL 中,因此您必须添加它。

      但是,如果您尝试在 C# 中执行功能,那么无论如何您可能都会有一个帮助程序库,所以这没什么大不了的。

      【讨论】:

        猜你喜欢
        • 2011-01-12
        • 2012-02-09
        • 2010-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-10
        相关资源
        最近更新 更多