优雅的抽象索引遍历方法

时间:2019-10-15 14:21:22

标签: c# linq

我有两种方法做的完全相同,只是一种方法检查从Current向前的索引范围,另一种方法检查从Current反向的范围索引。我已经对功能进行了抽象,以便通用代码在一种方法中,并且只使用IEnumerable作为参数来知道要遍历的索引范围。所以现在我的两种方法简化为:

private List<Thingy> GetForwardThingies()
{
    var indices = new List<int>();
    for (var i = _project.Current; i < _project.GetLimit(); i++)
        indices.Add(i);
    return GetThingiesByIteratingOverIndices(indices);
}

private List<Thingy> GetBackwardsThingies()
{
    var indices = new List<int>();
    for (var i = _project.Current; i >= 0; i--)
        indices.Add(i);
    return GetThingiesByIteratingOverIndices(indices);
}

是否有一种更优雅的方式(也许使用LINQ)来封装这种抽象? GetThingiesByIteratingOverIndices速度很快,并且对速度没有要求,因为它将在不超过几十个索引上运行,因此效率不是主要问题。我当时在想C#8.0中的新System.Range东西可能会有所帮助,但可惜它不允许表达向后范围。 (而且,是的,顺序很重要,所以我不能从0转到Current来获得Backward Thingies。)

新信息

好的,我试图使其保持简单,但是我想我需要给出 GetThingiesByIteratingOverIndices 的真实实现:

private List<ScriptLine> GetRecordableBlocksUpThroughHole(IEnumerable<int> indices)
{
    var bookInfo = _project.SelectedBook;
    var chapter = _project.SelectedChapterInfo.ChapterNumber1Based;
    var lines = new List<ScriptLine>();
    foreach (var i in indices)
    {
        if (!_project.IsLineCurrentlyRecordable(bookInfo.BookNumber, chapter, i))
            break;
        var block = bookInfo.ScriptProvider.GetBlock(bookInfo.BookNumber, chapter, i);
        lines.Add(block);
        if (!block.Skipped && !ClipRepository.GetHaveClip(_project.Name, bookInfo.Name, chapter, i, _project.ScriptProvider))
            return lines;
    }
    return new List<ScriptLine>();
}

1 个答案:

答案 0 :(得分:3)

private List<Thingy> GetForwardThingies() =>
    _whateverEnumerableYouAreIterating.Skip(_project.Current)
                                      .ToList();

private List<Thingy> GetBackwardsThingies() =>
    _whateverEnumerableYouAreIterating.Take(_project.Current - 1)
                                      .Reverse()
                                      .ToList();

当然,急切地迭代(.ToList())完全是可选的;您总是可以返回IEnumerable<Thingy>并将执行推迟到调用者决定的时候。

在两种情况下,您的代码都可能更有效(SkipReverse可能会比较昂贵),但是如果迭代项的数量很少,那么正确地处理就不会成为问题承担您的问题。