我有一个定义列表和两个循环函数的类,它们查找列表中具有某些属性的项。这两个循环函数可以组合成一个更通用的循环函数,它将内部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;
}
}
答案 0 :(得分:4)
是的,如果您使用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;
}
}
正如其他人所提到的,在这个特殊情况下,已经有一个相对简洁的构造用于你正在进行的过滤(改进了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();
}
}
答案 1 :(得分:0)
简单的LINQ调用如何:
List<int> res = list.Select(x => x.SomeFunc).Union(list.Select(y => y.SomeFunc2))
答案 2 :(得分:-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();
}