2012-03-30 13 views
1

私はこの問題に数時間悩まされています。私はウサギの穴から遠く離れすぎていると思っています。私は完全にあきらめる前に、私は誰かが私のために、この上でいくつかの光を当てることができるかもしれない願っています...GroupByとSelectManyを使って一斉に

public class Object 
{ 
    public Object() 
    { 
     Properties = new List<Property>(); 
    } 

    public int Id { get; set; } 
    public IList<Property> Properties { get; set; } 
} 

public class Property 
{ 
    public string Name { get; set; } 
    public dynamic Value { get; set; } 
} 

    [Test] 
    public void ShouldBeAbleToGroupAnArrayOfObjectsByASpecificProperty() 
    { 
     // Arrange 
     var objects = new List<Object>(); 
     var doorObject = new Object() { 
           Properties = new List<Property>() {new Property() {Name = "Level", Value = "Level 1"}} 
          }; 

     var wallobject = new Object() { 
           Properties = new List<Property>() { new Property() { Name = "Level", Value = "Level 2" } } 
          }; 

     var chairObject = new Object() { 
            Properties = new List<Property>() { new Property() { Name = "Level", Value = "Level 2" } } 
           }; 

     objects.Add(doorObject); 
     objects.Add(wallobject); 
     objects.Add(chairObject); 

     // Act 
     var groupBy = objects.SelectMany(obj => obj.Properties).GroupBy(props => props.Value); 

     // Assert 
     Assert.That(groupBy.Count(), Is.EqualTo(2)); 
    } 

このテストはパスするが、問題は、私は、プロパティの配列を返すんだということです。私はオブジェクトの配列を取得しようとしています。私がしようとしていることは可能ですか?

objects.GroupBy(obj => obj.Properties.First().Value); 

または

objects.GroupBy(obj => obj.Properties.First(p => p.Name == "Level").Value); 
+0

私が正しく理解している場合は、オブジェクトを「レベル」プロパティでグループ化しようとしています。複数の異なる値のプロパティを持つオブジェクトがある場合、何が起こりたいですか? – tzaman

+0

@tzaman - 私はその質問を理解しているかどうか分かりません。プロパティは確かに異なる値を持つことができます。上記の例では、最終的な結果を得たいと思います。オブジェクトのグループ化されたセットは、すべてプロパティコレクションの「値」によってグループ化されています。私は現時点で否定的なテストケースに心配していません。それは役に立ちますか? –

+0

そのコレクション内の値が異なる場合は、どのグループに入るべきオブジェクトですか?つまり、fooObjectのプロパティセットに「レベル1」と「レベル2」の両方があるとしたら、それは2つのグループに分かれていますか? – tzaman

答えて

1

。これにより、簡単にナビゲートしてグループを実行することができます。

var stretched = objects.SelectMany(x => x.Properties, (x, property) => new 
{ 
    Object = x, 
    Property = property 
}); 

var q = stretched.GroupBy(x => x.Property.Value, x => x.Object); 
+0

Andrew、私は十分にありがとう。私は3時間キーボードに頭を打ち、私はそれに気付かなかったとは信じられません。とても簡単。どうもありがとうございます。 –

+0

これは本当に適切なソリューションですか?私が理解しているように、あなたはAマッチングプロパティに基づいてオブジェクトをグループ化する必要があります。このソリューションでは、最初のプロパティに一致します。 – Polity

+0

私はそれを午前中にテストに入れようとしているので、まだ正しい解決策を出していません。ただし、2番目のオプションは、 "レベル"という名前の最初のプロパティを探します。最終的に、それは私がグループ化したいものです。 –

0

あなたはあなたのネット可算でそのプロパティを持つ各オブジェクトの組み合わせを与えるクエリを定義することができます。これについてはどのよう

+0

私は確かにこれもショットを与えるでしょう。ありがとう、政治。 –

0

達成したいことを表示したい場合は、それが良いでしょうか?例:

`Object A - property 1 {Name = "a"}, 2 {Name = "b"}, 3 {Name = "a"}` 
    `Object B - property 1 {Name = "a"}, 2 {Name = "b"}, 3 {Name = "a"}` 

How do you want to group 
    object A - property.Name = "a", values - 1, 3 
       property.Name = "b", values - 2 
    object B - property.Name = "a", values - 1, 3 
       property.Name = "b", values - 2 

または

property.Name = "a", values - 1, 3 (objectA), 1, 3 (object B) 
property.Name = "b", values - 2 (objectA), 2 (object B) 

または

property.Name = "a", a dictionary A (key - object A, values - 1, 3), a dictionary B (key - object B, values - 1, 3) 
    property.Name = "b", a dictionary A (key - object A, values - 2), a dictionary B (key - object B, values - 2) 
1

私は今あなたのユースケースについて理解何を考えると、私は、リストの代わりに、ちょうどあなたのプロパティセットを保存するためにDictionaryを使用してお勧めしたいですカスタムクラスの名前:値のペアが必要なだけで、名前ごとに1つの値が必要なので、当然です。これは、(プロパティ名を指定して)あなたのためにグループ化を行う必要があり、あなたがvar Properties = new Dictionary<string, dynamic>()に行くと仮定すると、

var groupBy = objects.GroupBy(obj => obj.Properties['Level']); 

これはobjects内のすべてのオブジェクトはしかし、その性質に'Level'の値を持っていることを前提としています。

+0

正直言って、これはまさに私が変更しようとしているものです。私はKeyedCollection を継承するPropertyCollectionを実装しようとしています。これは、項目を辞書に追加するためのより簡単なインターフェースを提供したいと考えています。私の電球を蹴ってくれてありがとう。 –

関連する問題