簡體   English   中英

根據屬性的最小值從集合中查找項目

[英]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包含以下每個值的MyItem:1、5和7
  • MyGroup2包含以下每個值的MyItem:3和
    8
  • MyGroup3包含以下每個值的MyItem: 2、4、5和7

然后,返回的值將是MyGroup1 (作為單個項目列表),因為它包含的值1是所有值中的最小值。

但是,如果存在多個具有最低值的值,例如:

  • MyGroup1包含以下每個值的MyItem:1、5和7
  • MyGroup2包含以下每個值的MyItem:3和8
  • MyGroup3包含以下每個值的MyItem: 1、4、5和7

然后它將在列表中返回MyGroup1MyGroup3

提前致謝。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM