根据属性的最小值从集合中查找项目

时间:2012-07-06 15:47:55

标签: c# linq lambda

我定义了以下对象:

public class MyGroup
{
    public MyItem[] Items;
}

public class MyItem
{
    public int Val;
}

假设我有一个List列表,其中每个MyGroup对象包含不同数量的MyItems;这反过来包含Val的变化值。

如何在所有MyGroup对象中找到包含最低Val的MyGroup对象子集。

E.g: 如果我使用以下值定义列表

  • 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

然后它会在列表中返回 MyGroup1 MyGroup3

提前致谢。

5 个答案:

答案 0 :(得分:5)

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

这将是一个两遍算法。如果你有足够的动力,你可以在一次通过中通过跟踪包含最小值的所有项目来搜索最小值。

答案 1 :(得分:1)

    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,忽略Key

答案 2 :(得分:0)

   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;

答案 3 :(得分:0)

这是我刚为此写的代码段。它是IEnumerable<T>的扩展方法,它返回一个基于&#34; sort&#34;的最小元素。功能(没有实际排序,或执行两次传球,没有在两次传球时发生的比赛条件)。

/// <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;
}

答案 4 :(得分:-2)

将此添加到您的Linq查询:.FirstOrDefault();你只得到一个价值。