如何使用 C# 代码重写这个使用扩展运算符的 javascript 函数?

How to rewrite this javascript function that uses spread operator using C# code?

我正在尝试使用 C# 代码重写此 的答案。由于 C# 没有普及,而且我们遇到越界异常,这是一项艰巨的任务。我设法编写了以下代码,它的工作原理,但我相信有更好的方法来做到这一点。

 int? result = MaxCollectableTreasure(new List<int?>() {1, 3, 1, 8, 7 }, 3);
    
    int? MaxCollectableTreasure(List<int?> chests, int minutes)
    {
        if (chests.Count == 1 && minutes > 0)
            return chests[0];
    
        int? firstElement = chests[0];
        var restOfList = chests.Skip(1).Take(chests.Count).ToList();
    
        return MaxCollectableTreasuresRecursive(firstElement, restOfList, minutes);
    }
    
    int? MaxCollectableTreasuresRecursive(int? firstElement, List<int?> chests, int minutes)
    { 
        if (minutes == 0 || firstElement is null)
            return 0;
    
        if (firstElement == 0)
            return MaxCollectableTreasuresRecursive(chests.FirstOrDefault(), AllButFirst(chests), minutes - 1);
    
        var left = firstElement + MaxCollectableTreasuresRecursive(0, AllButFirst(chests.Prepend(0)), minutes - 1);
        var right = MaxCollectableTreasuresRecursive(chests.FirstOrDefault(), AllButFirst(chests), minutes - 1);
    
        int leftAsInt = left ?? 0;
        int rightAsInt = right ?? 0;
    
        return Math.Max(leftAsInt, rightAsInt);
    }
    
    List<int?> AllButFirst(IEnumerable<int?> chests)
    {
        return chests.Skip(1).Take(chests.Count()).ToList();
    }

你在这里有一个非常漂亮的实现,它很快就解决了这个问题。

我只能看到你在这里的性能有微小的改进,这会增加执行时间。

int? result = MaxCollectableTreasure(new List<int?>() { 1, 3, 1, 8, 7 }, 3);

int? MaxCollectableTreasure(IReadOnlyList<int?> chests, int minutes)
{
    if (chests.Count == 1 && minutes > 0)
        return chests[0];

    int? firstElement = chests[0];
    var restOfList = chests.Skip(1);

    return MaxCollectableTreasuresRecursive(firstElement, restOfList, minutes);
}

int? MaxCollectableTreasuresRecursive(int? firstElement, IEnumerable<int?> chests, int minutes)
{
    while (true)
    {
        if (minutes == 0 || firstElement is null) return 0;

        if (firstElement == 0)
        {
            firstElement = chests.FirstOrDefault();
            chests = chests.Skip(1);
            minutes -= 1;
            continue;
        }

        var left = firstElement + MaxCollectableTreasuresRecursive(0, chests, minutes - 1);
        var right = MaxCollectableTreasuresRecursive(chests.FirstOrDefault(), chests.Skip(1), minutes - 1);

        int leftAsInt = left ?? 0;
        int rightAsInt = right ?? 0;

        return Math.Max(leftAsInt, rightAsInt);
    }
}

首先是您不需要 .Take().ToList() 来取回箱子,只需 .Skip() 自己就可以完成您需要的事情。

同样在计算左边的值时,您将 0 添加到胸部,然后在其上跳过 1,以便可以将其删除以整理该位。

不过必须说,您对 Javascript 等价物的解释非常巧妙!