2017-02-20 18 views
1

新しい匿名型(コレクション)を作成するC#コードがあります。コレクション内のエントリは、Child.Valueだけによって異なります。私が達成しようとしているのは、すべての親の各子供の最高値を持つ親子ペアを得ることによって、子の重複なしに親子ペアの数を減らすことです。子供たちは、子供たちによって区別されます。あなたはそれぞれの親のための単一の親子ペアが必要な場合は匿名型コレクションフィルタ

var familyPairs = family 
     .SelectMany(parent => parent.Children, (parent, child) => 
       new { 
        Parent = parent, 
        Child = child 
        }) 
     .OrderByDescending(pair => pair.Child.Value); 

答えて

2

、あなたは簡単な選択を使用することができます。

family.Select(p => new { 
    Parent = p, 
    Child = p.Children.OrderByDescending(c => c.Value).FirstOrDefault() 
}) 

それとも、子供のいない親のためのペアをしたくない場合は - 自由な子をフィルタリング親:あなたのアップデート後

family.Where(p => p.Children.Any()).Select(p => new { 
    Parent = p, 
    Child = p.Children.OrderByDescending(c => c.Value).First() 
}) 

それはあなたがSelectManyが必要であることが判明していますが、idでグループの子どもたちに必要そして、最大値を持つ各グループの子から選択します。

family.SelectMany(
    p => p.Children.GroupBy(c => c.Id) 
        .Select(g => g.OrderByDescending(c => c.Value).First()), 
    (p,c) => new { Parent = p, Child = c }) 
+0

を、私はそれを試してみます。 :) –

+0

申し訳ありませんが、私はあなたの編集について何か出てくる私の質問を編集しました。しかし、私はまだこれを試してみる:) –

+0

@CeylanMumunKocabaşあなたの編集からは明らかではない - 親の子供リストに同じ子供のための複数のエントリがある場合、どのように2人の異なる子供を区別していますか? –

2

あなたが唯一最大の子供をしたい場合は、ソートは時間の無駄である(nは子供のリストについては、n個の操作をログに記録)。代わりに、Aggregate()拡張メソッドを使用して、子の各リストを一度反復して、子を最大値で取得する必要があります。

family.Select(p => new { 
Parent = p, 
Child = p.Children.Aggregate((c1, c2) => c1.Value > c2.Value ? c1 : c2)}) 

参照してください:How can I get LINQ to return the object which has the max value for a given property?

+0

また、複数の子供が最大値を共有する場合、>と> =の間に大きな違いがあることを指摘しておきます。 >演算子は最後の子を最大値で選択し、> =は最初のものを選択します。 – plushpuffin