2016-05-06 72 views
1

如何使用LINQ如何陣列使用LINQ

得到的陣列控制最低位置得到控制最低的位置,我有控件數組說 暗淡oClipboard()作爲控制

我所需要的控制它具有從塔oclipboard最低位置或最小位置值

到目前爲止我試圖與LINQ min函數

Dim p = c.Select(Function(g) g.Location).Min.ToString 
Dim x = c.Select(Function(g) g).Min(Function(h) h.Location) 

上下兩個給我的錯誤以下

System.ArgumentException was unhandled 
HResult=-2147024809 
Message=At least one object must implement IComparable. 
Source=mscorlib 
StackTrace: 
at System.Collections.Comparer.Compare(Object a, Object b) 
at System.Collections.Generic.ObjectComparer`1.Compare(T x, T y) 
at System.Linq.Enumerable.Min[TSource](IEnumerable`1 source) 
at System.Linq.Enumerable.Min[TSource,TResult](IEnumerable`1 source, Func`2 selector) 

說有什麼辦法我能得到whhich具有最低的位置

+1

你是指什麼*最低的位置*?該位置由2個座標定義:X和Y.因此,請更準確地定義您想要找到的控件 - 位於最左側還是最下方或這些2的某個組合的位置? –

+0

我知道這是個醜陋的問題,但我需要最接近(0,0)或至少最低的y值 – Dandy

+0

你是什麼意思控制?你爲什麼使用剪貼板? – jdweng

回答

1

如果你指的是控制最低位置,這有(0,0)最短歐氏距離點你可以使用Aggregate擴展方法:

Control[] oClipboard = ...; 
Control control = oClipboard.Aggregate((curMin, c) => (curMin == null || Math.Sqrt(c.Location.X * c.Location.X + c.Location.Y * c.Location.Y) < Math.Sqrt(curMin.Location.X * curMin.Location.X + curMin.Location.Y * curMin.Location.Y) ? c : curMin)); 

,或者如果你只是想找到最小控制Y座標:

Control control = oClipboard.Aggregate((curMin, c) => (curMin == null || c.Location.Y < curMin.Location.Y ? c : curMin)); 

現在所有作爲練習留給你的是將其轉換爲VB.NET。

+0

它似乎在爲我工作,但會請用英語解釋你有什麼我可以理解的相同 – Dandy

+0

有人請你解釋一下上面的代碼,因爲我是新來的linq – Dandy

+1

The聚合擴展方法需要2個參數:某些條件的當前候選元素和正在迭代的當前元素。您有責任比較這兩項,並通過應用所需的功能來決定哪一項返回。在我的例子中,我計算當前候選('curMin')和當前元素('c')之間的(0,0)點的歐幾里德距離,如果距離較近,則返回當前元素,否則返回當前元素最小。 –

1

一個Point沒有實現IComparable控制。你想如何比較兩點?

您可以提供自定義IEqualityComparer<Point>並將實例傳遞給MinMax。如果你只在X-Coordinate感興趣,例如,你也可以使用這樣的:

Dim pxMin As Int32 = c.Select(Function(g) g.Location.X).Min() 

如果你想使用匿名類型的控制,你可以使用這種方法:

Dim controlPoints = From c in Me.Controls.Cast(Of Control)() 
        Select controlLoc = New With { .Control = c, .Location = c.Location } 
        Order by controlLoc.Location.X , controlLoc.Location.Y 
Dim minLocControl As Control = controlPoints.First().Control 

如果你想處理這兩個控件可能有重疊的位置的情況下:

Dim orderedControlPointGroups = 
    From c In Me.Controls.Cast(Of Control)() 
    Order By c.Location.X, c.Location.Y 
    Group By c.Location Into controlGroups = Group 

Dim minLocControlGroup = orderedControlPointGroups.First() 
Dim minLocation as Point = minLocControlGroup.Location 
Dim allMinControls as IEnumerable(of Control) = minLocControlGroup.controlGroups 
+0

它給了我點我需要控制retrun或其名稱作爲回報 – Dandy

+0

解決方案是兩個控件的情況下給我邏輯錯誤,因爲只有2個按鈕位於同一位置和('allMinControls')給出長度爲3的重複2個控件之一 – Dandy

+0

@dandy:我無法重現它。用兩個位於同一位置的4個按鈕進行測試。只有這兩個在'allMinControls' –