如何从控件数组中以最小的面积获得控制?



我有一个控件数组:

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)将再次迭代第一个元素。如果您不希望这样做,请使用GetEnumeratorMoveNext进行枚举:

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();

最新更新