IEnumerable,其中全部满足 X 并且至少有一个满足 y
我有 2 个 IEnumerable
。例如 {0,0.1,0.5,1}
和 {a,b,c,d}
假设长度相等
示例域对象代码:
public class Foo //does not implement IEnumerable because nothing outside of itself should treat it as such
{
private readonly decimal _a;
private readonly decimal _b;
private readonly decimal _c;
//another class also has private readonly decimal _d;
public decimal A {get{return _a;}}
//...
public decimal C {get{return _c;}}
}
amp
- 如果全部满足
>=
(如Foo1.A>=Foo2.A & ;& ' .. 'Foo1.C>=Foo2.C
..) - 至少一个
>
(如Foo1.B>Foo2.B
>)
示例迭代代码:
//DRY violation, but probably the shortest route to the goal
private static IEnumerable<Func<Foo,decimal>> Accessors=
new List{f=>f.A,f=>f.B,f=>f.C};
public static bool operator>(Foo foo1, Foo foo2)
{
if (foo1==null||foo2==null)
return false;
bool foundGreater=false;
foreach (var accessor in _Accessors)
{
if (accessor(foo1)<accessor(foo2))
return false;
if (foundGreater==false&&accessor(foo1)>accessor(foo2))
foundGreater=true;
}
return foundGreater;
}
从学习的角度来看,涉及 zip 的信息和答案受到欢迎,就像使用不涉及反射的相同比较功能来解决可变属性长度的整个问题一样。
不过,我目前正在 .net 2.0 的范围内使用 LinqBridge 进行工作。
我正在考虑类似下面的内容来涵盖需要相同功能的所有类
//Needs a better name for sure
public static bool AllWithAny<T,TValue>(IEnumerable<Func<T,TValue>> accessors,T item1, T item2,
Func<TValue,TValue,bool> shortCircuitBreak,Func<TValue,TValue,bool> atLeastOneCondition)
{
GuardStrategy.ThrowIfNull(accessors,"accessors");
GuardStrategy.ThrowIfNull(item1, "item1");
GuardStrategy.ThrowIfNull(item2, "item2");
var foundOne=false;
foreach(var accessor in accessors)
{
var values=new {Value1=accessor(item1),Value2=accessor(item2)};
if (shortCircuitBreak(values.Value1, values.Value2))
return false;
if(foundOne==false && atLeastOneCondition(values.Value1,values.Value2))
{
foundOne=true;
}
}
return foundOne;
}
问题:
是否存在现有的 Linq 关键字/运算符组合可以更优雅地完成所有这一切? 是否有一种更优雅/更简单的方法来进行这种类型的比较,即更好的 DRY、更少的编码和更多的重用?
I have 2 IEnumerable<decimal>
. for example {0,0.1,0.5,1}
and {a,b,c,d}
assume equal lengths
Sample Domain Object Code:
public class Foo //does not implement IEnumerable because nothing outside of itself should treat it as such
{
private readonly decimal _a;
private readonly decimal _b;
private readonly decimal _c;
//another class also has private readonly decimal _d;
public decimal A {get{return _a;}}
//...
public decimal C {get{return _c;}}
}
I want to define Foo1>Foo2
- if all meet
>=
(as inFoo1.A>=Foo2.A && ' .. 'Foo1.C>=Foo2.C
..) - At least one
>
(as inFoo1.B>Foo2.B
)
Sample iterative code:
//DRY violation, but probably the shortest route to the goal
private static IEnumerable<Func<Foo,decimal>> Accessors=
new List{f=>f.A,f=>f.B,f=>f.C};
public static bool operator>(Foo foo1, Foo foo2)
{
if (foo1==null||foo2==null)
return false;
bool foundGreater=false;
foreach (var accessor in _Accessors)
{
if (accessor(foo1)<accessor(foo2))
return false;
if (foundGreater==false&&accessor(foo1)>accessor(foo2))
foundGreater=true;
}
return foundGreater;
}
information and answers involving zip are welcomed from a learning perspective, as are attacking the entire problem of variable property lengths using the same comparison functionality that don't involve reflection.
However, I'm currently working within the confines of .net 2.0 with LinqBridge.
I'm considering something like the following to cover all classes that need the same functionality
//Needs a better name for sure
public static bool AllWithAny<T,TValue>(IEnumerable<Func<T,TValue>> accessors,T item1, T item2,
Func<TValue,TValue,bool> shortCircuitBreak,Func<TValue,TValue,bool> atLeastOneCondition)
{
GuardStrategy.ThrowIfNull(accessors,"accessors");
GuardStrategy.ThrowIfNull(item1, "item1");
GuardStrategy.ThrowIfNull(item2, "item2");
var foundOne=false;
foreach(var accessor in accessors)
{
var values=new {Value1=accessor(item1),Value2=accessor(item2)};
if (shortCircuitBreak(values.Value1, values.Value2))
return false;
if(foundOne==false && atLeastOneCondition(values.Value1,values.Value2))
{
foundOne=true;
}
}
return foundOne;
}
The Question(s):
Is there an existing Linq keyword/operator combination that will do all this more gracefully?
Is there a more elegant/simpler way to do this type of comparison that is better DRY, less coding, and more reuse?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是可行的(使用 @gaeron 的想法来公开值的
IEnumerable
以便于访问)基本思想是
foo1
大于foo2
,foo1.Values
中的每个元素与foo2.Values
中相应的元素相减必须 >=0 并且必须至少有一个条目 >=0 0。This would work (using @gaeron's idea to expose
IEnumerable
of values to ease access)The basic idea is that for
foo1
to be greater thanfoo2
, the subtraction of each element infoo1.Values
with the corresponding one infoo2.Values
must be >=0 AND there must at least be one entry that is > 0.尚未测试,但只需稍加修改就应该可以工作。
PS我不太明白你的问题,所以我只是实现了你一开始所问的内容。
Haven't tested but with little modifications it should work.
P.S. I didn't quite understand your question so I just implemented what you asked in the beginning.