将两个循环函数合并为一个

本文关键字:一个 合并 两个 循环 函数 | 更新日期: 2023-09-27 17:53:00

我有一个类,它定义了一个列表和两个循环函数,用于查找列表中具有某些属性的项。这两个循环函数可以组合成一个更通用的循环函数,有内部Bar.Function()作为参数吗?

class Foo {
    List<Bar> bar;
    List<int> SomeFunc() {
        List<int> list;
        for (i...) {
           if (bar[i].IsSomething()) {
               list.Add(i);
           }
        }
        return list;
    }

    List<int> SomeOtherFunc() {
        List<int> list;
        for (i...) {
           if (bar[i].IsSomethingElse()) {
               list.Add(i);
           }
        }
        return list;
    }
}

将两个循环函数合并为一个

是的,如果您使用lambdas:

,这很容易。
class Foo 
{
        List<Bar> bar;
        List<int> SomeFunc()
        {
            return LoopedTest(b => b.IsSomething());
        }

        List<int> SomeOtherFunc()
        {
            return LoopedTest(b => b.IsSomethingElse());
        }
        private List<int> LoopedTest(Predicate<Bar> test)
        {
            List<int> list = new List<int>();
            for (int i = 0; i < bar.Count; i++)
            {
                if (test(bar[i]))
                {
                    list.Add(i);
                }
            }
            return list;
        }
}

正如其他人所提到的,在这个特殊情况下,已经有一个相对简洁的结构用于您正在进行的过滤(根据phog的建议进行了改进):

return IEnumerable.Range(0, bar.Count).Where(i => bar[i].IsSomething()).ToList();

你也可以把这两种解决方案结合起来,得到一些非常干净的代码:

class Foo 
{
        List<Bar> bar;
        List<int> SomeFunc()
        {
            return FindIndexes(b => b.IsSomething());
        }
        List<int> SomeOtherFunc()
        {
            return FindIndexes(b => b.IsSomethingElse());
        }
        private List<int> FindIndexes(Predicate<Bar> test)
        {
            return IEnumerable.Range(0, bar.Count).Where(i => test(bar[i])).ToList();
        }
}

一个简单的LINQ调用如何:

 List<int> res = list.Select(x => x.SomeFunc).Union(list.Select(y => y.SomeFunc2))

如果您需要匹配的索引列表作为获得项目本身列表的前兆,您可以使用Linq:

var selection = bar.Where(b => b.IsSomething()).ToList();

因为这只是Linq的一个单独的语句,你可能不需要把它放在它自己的方法中,但是如果你这样做了,它看起来像这样:

private List<Bar> SomeFunc(Predicate<Bar> test)
{
    return bar.Where(test).ToList();
}

如果你真的是在索引之后,那么在Linq中它看起来像这样:

var selection = bar.Select((b, i) => new { b, i })
                .Where(x => x.b.IsSomething())
                .Select(x => x.i)
                .ToList();

分解成一个方法,那就是:

private List<Bar> SomeFunc(Predicate<Bar> test)
{
    return bar.Select((b, i) => new { b, i })
                .Where(x => test(x.b))
                .Select(x => x.i)
                .ToList();
}