0

我有一个定义列表的类和两个循环函数,它们在列表中找到具有某些属性的项目。这两个循环函数是否可以组合成一个更通用的循环函数,以内部 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;
    }

}
4

3 回答 3

4

是的,如果您使用 lambda,这很容易:

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;
        }

}

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

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();
        }
}
于 2013-01-15T02:25:11.000 回答
0

一个简单的 LINQ 调用怎么样:

 List<int> res = list.Select(x => x.SomeFunc).Union(list.Select(y => y.SomeFunc2))
于 2013-01-15T02:25:42.790 回答
-1

如果您在获取匹配索引列表作为获取项目本身列表的前导,则可以使用 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();
}
于 2013-01-15T02:25:19.360 回答