【问题标题】:Normalizing chains of .Skip() and .Take() calls规范化 .Skip() 和 .Take() 调用链
【发布时间】:2010-03-26 13:01:09
【问题描述】:

我正在尝试将.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;
    }
}

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

【问题讨论】:

  • 出于好奇,这是干什么用的?
  • @NickLarsen:我正在实现一个 LINQ 查询提供程序,需要将 Skip 和 Take 调用转换为单个偏移量/计数对。
  • 不确定它们的行为,但按照假定的逻辑,我相信你应该有 .Skip(5).Take(7).Take(3) => .Skip(5).Take(3 )(即取 3 而不是 4)。您的代码似乎也给出了这个值,我认为这是正确的
  • @rslite:你是对的。好收获!

标签: c# linq iqueryable


【解决方案1】:

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

“正确”是相当主观的,但这些例子看起来很合理。

另外,我会规范化 .Skip(0) 调用。

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

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

可能应该被规范化为.Take(0)


编辑:

skip的官方定义:

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

并采取:

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

根据您的示例,我认为您的测试用例完全符合规范。

【讨论】:

  • 问题不在于实现我自己的规范,而是找到“正确”的规范,因为我不是在开发自己的查询框架而是插入到 LINQ 中。是否有任何官方文档 LINQ Skip/Take 实现应该如何表现?
  • 是的,文档并没有明确说明应该如何评估链,但是从这些规范来看,我同意我的测试用例(我从直觉得出的)看起来很理智。我想我必须编写更多的测试用例来捕捉所有边缘情况并相应地更新算法。
猜你喜欢
  • 2014-10-04
  • 2018-02-03
  • 2022-01-19
  • 2020-12-25
  • 2012-06-12
  • 1970-01-01
  • 2021-08-25
  • 2018-03-05
  • 1970-01-01
相关资源
最近更新 更多