规范化.Skip()和.Take()调用的链

时间:2010-03-26 13:01:09

标签: c# linq iqueryable

我正在尝试将.Skip().Take()来电的任意链标准化为单个.Skip()来电,然后是可选的单.Take()来电。

以下是预期结果的一些示例,但我不确定这些是否正确:

.Skip(5)                        => .Skip(5)
.Take(7)                        => .Skip(0).Take(7)

.Skip(5).Skip(7)                => .Skip(12)
.Skip(5).Take(7)                => .Skip(5).Take(7)
.Take(7).Skip(5)                => .Skip(5).Take(2)
.Take(5).Take(7)                => .Skip(0).Take(5)

.Skip(5).Skip(7).Skip(11)       => .Skip(23)
.Skip(5).Skip(7).Take(11)       => .Skip(12).Take(11)
.Skip(5).Take(7).Skip(3)        => .Skip(8).Take(4)
.Skip(5).Take(7).Take(3)        => .Skip(5).Take(4)
.Take(11).Skip(5).Skip(3)       => .Skip(8).Take(3)
.Take(11).Skip(5).Take(7)       => .Skip(5).Take(6)
.Take(11).Take(5).Skip(3)       => .Skip(3).Take(2)
.Take(11).Take(5).Take(3)       => .Skip(0).Take(3)

任何人都可以确认这些是预期的正确结果吗?


以下是我从示例中得出的基本算法:

class Foo
{
    private int skip;
    private int? take;

    public Foo Skip(int value)
    {
        if (value < 0)
            value = 0;

        this.skip += value;

        if (this.take.HasValue)
            this.take -= value;

        return this;
    }

    public Foo Take(int value)
    {
        if (value < 0)
            value = 0;

        if (!this.take.HasValue || value < this.take)
            this.take = value;

        return this;
    }
}

我知道如何确认这是否是正确的算法?

1 个答案:

答案 0 :(得分:4)

这是TDD的完美场景。鉴于您已经在上面定义了您的规范,这应该是 cake ,以实现一系列的一系列测试。

“正确”是相当主观的,但这些例子似乎是理智的。

此外,我会规范化.Skip(0)来电。

确保清楚地定义边缘情况。例如,

.Take(11).Skip(12).Take(1)

应该归一化为.Take(0)

<小时/> 修改

skip的官方定义:

  

跳过序列中指定数量的元素,然后返回其余元素。

并采取:

  

从序列的开头返回指定数量的连续元素。

根据您的示例,我认为您的测试用例正确遵循规范。