2

次のオブジェクトを定義しています。

public class MyGroup
{
    public MyItem[] Items;
}

public class MyItem
{
    public int Val;
}

各MyGroupオブジェクトにさまざまな数のMyItemが含まれているリストとしてリストがあるとします。これには、Valのさまざまな値が含まれています。

すべてのMyGroupオブジェクトの中で最も低いValを含むMyGroupオブジェクトのサブセットを見つけるにはどうすればよいですか。

例:次の値でリストを定義した場合

  • MyGroup1には、1、5、および7の各値のMyItemが含まれています。
  • MyGroup2には、次の各値のMyItemが含まれています:3および、
    8
  • MyGroup3には、2、4、5、および7の各値のMyItemが含まれています。

その場合、戻り値はMyGroup1(単一アイテムリストとして)になります。これは、すべての値の中で最も低い値1が含まれているためです。

ただし、次のように最小値の値が複数ある場合:

  • MyGroup1には、1、5、および7の各値のMyItemが含まれています。
  • MyGroup2には、次の各値のMyItemが含まれています:3および、8
  • MyGroup3には、1、4、5、および7の各値のMyItemが含まれています。

次に、MyGroup1MyGroup3をリストに返します。

前もって感謝します。

4

5 に答える 5

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

これは2パスアルゴリズムになります。適切な動機があれば、最小値を検索しながら最小値を含むすべてのアイテムを追跡することで、1回のパスでそれを行うことができます。

于 2012-07-06T15:57:09.780 に答える
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のみを選択し、キーを無視します

于 2012-07-06T16:04:42.177 に答える
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;
于 2012-07-06T16:08:26.850 に答える
0

これが私が今書いたコードスニペットです。これはへの拡張メソッドIEnumerable<T>であり、「sort」関数に基づいて最小要素を返します(実際にソートを実行したり、2つのパスを実行したりせず、2つのパスを実行したときに発生する競合状態を発生させません)。

/// <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;
}
于 2015-03-02T05:28:04.227 に答える
-2

これをLinqクエリに追加します:.FirstOrDefault(); 値は1つだけです。

于 2012-07-06T15:58:15.923 に答える