我有一系列控件:
Control[] controls = getControls();
我需要以最小的面积获得控件。我知道我可以像这样对它进行排序并获得索引0中的控制权:
var min = filtered.OrderBy(x => x.Height * x.Width).ToArray()[0];
但是如何在不订购控件的情况下获取它?
答案 0 :(得分:2)
这可以通过非常强大但未充分利用的Aggregate
方法来实现:
var min = controls.Aggregate((x, y) => x.Height * x.Width < y.Height * y.Width ? x : y);
您可以使用Control
属性扩展Area
类,以避免在Aggregate
方法中重复乘法代码。
答案 1 :(得分:1)
您可以为此使用Enumerable.Aggregate。 that,该函数会一遍又一遍地计算出最小控件的大小。
If与创建所有linq函数类似,可以更有效(且更易于创建)创建扩展函数,该扩展函数接受Controls
序列并返回最小的扩展函数。参见extension methods demystified
// extension function: gets the size of a control
public static int GetSize(this Control control)
{
return (control.Height * control.Width);
}
// returns the smallest control, by size, or null if there isn't any control
public static Control SmallestControlOrDefault(this IEnumerable<Control> controls)
{
if (controls == null || !controls.Any()) return null; // default
Control smallestControl = controls.First();
int smallestSize = smallestControl.GetSize();
// check all other controls if they are smaller
foreach (var control in controls.Skip(1))
{
int size = control.GetSize();
if (size < smallestSize)
{
smallestControl = control;
smallestSize = size;
}
}
return smallestControl;
}
Skip(1)
将再次遍历第一个元素。如果您不希望这样做,请使用GetEnumerator
和MoveNext
进行枚举:
var enumerator = controls.GetEnumerator();
if (enumerator.MoveNext())
{ // there is at least one control
Control smallestControl = enumerator.Current;
int smallestSize = smallestControl.GetSize();
// continue enumerating the other controls, to see if they are smaller
while (enumerator.MoveNext())
{ // there are more controls
Control control = enumerator.Current;
int size = control.GetSize();
if (size < smallestSize)
{ // this control is smaller
smallestControl = control;
smallestSize = size;
}
}
return smallestControl;
}
else
{ // empty sequence
...
}
这样,您绝对可以确定自己只会枚举一次
用法:
IEnumerable<Control> controls = ...
Control smallestControl = controls.SmallestControlOrDefault();