c# - 可以将任意长度的参数数组转换为嵌套循环吗?

标签 c# loops syntax nested

有没有办法在 C#(或任何其他 Net 语言)中实现以下目标?

public double nestedParamArrayLoop(function delegatedFunction, LoopControllers loopControllers)
{
    double total = 0;

    NestedLoopControllers loopControllers = new NestedLoopControllers(loopController, loopMaxes);

    foreach(LoopController loopController in loopControllers);
    {
        nestedfor (loopController)
        {
            // this line results in one or more loopControllers being passed in
            total += delegatedFunction(loopController);
        }
    }

    return total;
}

public double delegatedFunction(params int[] arguments)
{
    // dummy function to compute product of values
    long product = 1;
    for (int i = 0; i < arguments.Count ; i++)
        product *= arguments[i];
    return product;
}

根据数组 loopControllers 中 Controller 的数量,调用 delegatedFunction 时使用可变数量的参数?每个 loopController 将包含一个起始值、一个最大值和一个增量值(即模板 for 循环)。

上面的语法不太有效,因为我不确定是否存在任何语法来捕捉这种范例。但想法是您可以指定任意数量的嵌套循环,然后由编译器(或运行时)为您完成嵌套。所以这是一种模板化嵌套,您可以在其中为任意数量的循环定义循环条件,然后环境会为您构建循环。

例如

  • NestedParamsArrayLoop(delegatedFunction, loopContoller1);导致迭代调用 delegatedFunction(values for loopValue1);
  • NestedParamsArrayLoop(delegatedFunction, loopContoller1, loopController2);结果是 对 delegatedFunction 的迭代调用(loopValue1 的值,loopValue2 的值);
  • NestedParamsArrayLoop(delegatedFunction,loopContoller1 的值,loopController2 的值,loopController3 的值);结果是 迭代调用 delegatedFunction(loopValue1, values for loopValue2, values for loopValue3);

这样做的目的是避免编写具有不同数量参数但逻辑的实际内容在它们之间是通用的单独函数。

我希望我已经很好地解释了这一点,但如果没有,请询​​问!

最佳答案

我认为这正是您想要做的。

LoopController 定义开始:

public class LoopController : IEnumerable<int>
{
    public int Start;
    public int End;
    public int Increment;

    private IEnumerable<int> Enumerate()
    {
        var i = this.Start;
        while (i <= this.End)
        {
            yield return i;
            i += this.Increment;
        }
    }

    public IEnumerator<int> GetEnumerator()
    {
        return this.Enumerate().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

现在您可以像这样定义NestedParamArrayLoop:

public double NestedParamArrayLoop(Func<int[], double> delegatedFunction, List<LoopController> loopControllers)
{
    double total = 0;

    foreach (LoopController loopController in loopControllers)
    {
        total += delegatedFunction(loopController.ToArray());
    }

    return total;
}

现在剩下的就简单了:

void Main()
{
    var loopControllers = new List<LoopController>()
    {
        new LoopController() { Start = 4, End = 10, Increment = 2 },
        new LoopController() { Start = 17, End = 19, Increment = 1 },
    };
    Console.WriteLine(NestedParamArrayLoop(DelegatedFunction, loopControllers));
}

public double DelegatedFunction(params int[] arguments)
{
    long product = 1;
    for (int i = 0; i < arguments.Count(); i++)
        product *= arguments[i];
    return product;
}

您甚至可以这样定义 NestedParamArrayLoop:

public double NestedParamArrayLoop(Func<int[], double> delegatedFunction, List<LoopController> loopControllers)
{
    return
        loopControllers
            .Select(lc => delegatedFunction(lc.ToArray()))
            .Sum();
}

这更像您想要的吗?

public double NestedParamArrayLoop(Func<int[], double> delegatedFunction, List<LoopController> loopControllers)
{
    Func<IEnumerable<int>, IEnumerable<IEnumerable<int>>> getAllSubsets = null;
    getAllSubsets = xs =>
        (xs == null || !xs.Any())
            ? Enumerable.Empty<IEnumerable<int>>()
            : xs.Skip(1).Any()
                ? getAllSubsets(xs.Skip(1))
                    .SelectMany(ys => new[] { ys, xs.Take(1).Concat(ys) })
                : new[] { Enumerable.Empty<int>(), xs.Take(1) };

    double total = 0;


    foreach (LoopController loopController in loopControllers)
    {
        foreach (var subset in getAllSubsets(loopController))
        {
            total += delegatedFunction(subset.ToArray());
        }
    }

    return total;
}

关于c# - 可以将任意长度的参数数组转换为嵌套循环吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47429351/

相关文章:

c# - 没有瓷砖 XNA 的 2D 游戏中的碰撞检测

loops - 如何在ansible循环中跳过空值

javascript - 如何显示停止循环的提示中的条目

Vim 无法自动识别 groff(联机帮助页)文件

c# - FTP创建文件夹并在C#中上传文件

c# - 如何向下转换为重载方法

c# - Visual Studio 不断创建已定义的事件处理程序

python - 在循环中修改 pandas 数据帧的条目

list - Spss语法如何使用标签列出值

ruby - block 是否作为参数传递?