我有一个控件数组:
Control[] controls = getControls();
我需要以最小的面积获得控制权。我知道我可以这样排序并在索引 0 中获得控制权:
var min = filtered.OrderBy(x => x.Height * x.Width).ToArray()[0];
但是,如何在不订购控件的情况下获取它呢?
这可以通过非常强大但未充分利用的Aggregate
方法来实现:
var min = controls.Aggregate((x, y) => x.Height * x.Width < y.Height * y.Width ? x : y);
可以使用Area
属性扩展Control
类,以避免Aggregate
方法中的乘法代码重复。
你可以使用 Enumerable.Aggregate 来实现此目的。唉,该函数将一遍又一遍地计算最小控件的大小。
If 创建采用一系列Controls
并返回最小序列的扩展函数更有效(且可读(,类似于所有其他 linq 函数。请参阅揭秘的扩展方法
// 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();