[英]Using LINQ, find the minimum value of an item property, in a collection, in a dictionary
[英]Find an item from collection based on the minimum value of a property
我定義了以下對象:
public class MyGroup
{
public MyItem[] Items;
}
public class MyItem
{
public int Val;
}
假設我有一個列表作為列表,其中每個MyGroup對象都包含不同數量的MyItems; 依次包含不同的Val值。
如何找到MyGroup對象的子集,該子集在所有MyGroup對象中包含最低的Val。
例如:如果我使用以下值定義列表
然后,返回的值將是MyGroup1 (作為單個項目列表),因為它包含的值1是所有值中的最小值。
但是,如果存在多個具有最低值的值,例如:
然后它將在列表中返回MyGroup1和MyGroup3 。
提前致謝。
int lowestValue = groups.SelectMany(group => group.Items)
.Min(item => item.Val);
IEnumerable<MyGroup> result = groups.Where(group =>
group.Items.Select(item => item.Val).Contains(lowestValue));
這將是兩遍算法。 如果您有適當的動力,則可以在搜索該最小值的同時跟蹤包含該最小值的所有項目,從而一次完成任務。
var myGroup1 = new MyGroup();
myGroup1.Items = Enumerable.Range (1,3).Select (x=> new MyItem {Val=x}).ToArray();
var myGroup2 = new MyGroup();
myGroup2.Items = Enumerable.Range (1,4).Select (x=> new MyItem {Val=x}).ToArray();
var myGroup3 = new MyGroup();
myGroup3.Items = Enumerable.Range (3,5).Select (x=> new MyItem {Val=x}).ToArray();
var groupList = new List<MyGroup>();
groupList.Add(myGroup1);
groupList.Add(myGroup2);
groupList.Add(myGroup3);
var filterGroups = groupList.Select ( x=>new {Group=x, Min=x.Items.Select( y=> y.Val).Min()}).GroupBy (x=>x.Min).OrderBy (x=>x.Key).Take(1).SelectMany (x=> x).Select (x=>x.Group);
由於嵌套的數據結構,最后一個查詢非常大。
以下是解釋
groupList
// MyGroup的列表
.Select ( x=>new {Group=x, Min=x.Items.Select( y=> y.Val).Min()})
//組列表和最小值
.GroupBy (x=>x.Min).OrderBy (x=>x.Key)
按最小值分組並排序
.Take(1)
//取得第一項
.SelectMany (x=> x)
//(MyGroups列表的最小值)
.Select (x=>x.Group)
; //僅選擇MyGroups,忽略鍵
var query = from gr in myGroups
where gr.Items.Any(x => x.Val ==
(from g in myGroups
from i in g.Items
orderby i.Val
select i.Val).FirstOrDefault())
select gr;
這是我為此編寫的代碼段。 它是IEnumerable<T>
的擴展方法,它基於“ sort”函數返回最小元素(實際上不執行排序或執行兩次遍歷,並且沒有兩次遍歷時發生的競爭條件)。
/// <summary>
/// Get the minimum element, based on some property, like a distance or a price.
/// </summary>
static public T MinElement<T>(this IEnumerable<T> list, System.Func<T, float> selector)
{
T ret = default(T);
float minValue = float.MaxValue;
foreach (T elem in list)
{
float value = selector(elem);
if (value <= minValue)
{
ret = elem;
minValue = value;
}
}
return ret;
}
將此添加到您的Linq查詢:.FirstOrDefault(); 而您只會得到一個價值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.