将两个循环函数合并为一个
本文关键字:一个 合并 两个 循环 函数 | 更新日期: 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();
}