LINQ Group By Sözlük Nesnesine


161

Ben oluşturmak için LINQ kullanmak çalışıyorum Dictionary<string, List<CustomObject>>bir gelen List<CustomObject>. Bu "var" kullanarak çalışmak için alabilirsiniz, ama anonim türleri kullanmak istemiyorum. İşte sahip olduğum şey

var x = (from CustomObject o in ListOfCustomObjects
      group o by o.PropertyName into t
      select t.ToList());

Ayrıca bir Cast<>()kez ben LINQ kitaplığından kullanarak denedim x, ama geçersiz bir döküm olmanın etkisi derleme sorunları olsun.


Var x = (ListOfCustomObjects o grubundaki CustomObject o öğesinden o.PropertyName öğesinin t içine t seçeneğini seçerseniz) ne olur? ToList ();
esastincy

44
Bunun için tasarlanmış ToLookup kullanmak yerine bunu yapmanız için herhangi bir neden var mı?
Jon Skeet

1
Jon, ToLookup'un bu durumda nasıl çalıştığına dair bir örnek verebilir misin? Bu LINQ yöntemine aşina değilim.
Atari2600

8
@JonSkeet Harikasın! (Yani, herkes zaten biliyordu, ama yine de.) ToLookup kullanmayı planlamamamın nedeni, şimdiye kadar hiç duymamıştım. Şimdi biliyorum!
neminem

1
Tamlık uğruna, var"anonim" bir tür kullanmak değil, "örtük" bir tür kullanmaktır. Anonim türler, derleyici tarafından yapıyı işlemek için oluşturulan yeni sınıflardır new { thing = "stuff" };. Örtük türler var olan sınıflardır, vardeğişken hemen atandığında bunlara başvurmak için uygun bir yoldur, değişken türü kendisine atanan nesnenin türünden çıkarılabilir. Anonim bir türe başvuran bir değişkeni bile örtük olarak yazabilirsiniz, örneğin:var a = new { thing = "stuff" };
Michael Blackburn,

Yanıtlar:


351
Dictionary<string, List<CustomObject>> myDictionary = ListOfCustomObjects
    .GroupBy(o => o.PropertyName)
    .ToDictionary(g => g.Key, g => g.ToList());

6
Liste değeri olarak 'CustomObject' den bir özelliğe ihtiyacınız yoksa (bu cevapta gösterilmez), kodelliğini Jon Skeet'in ToLookup () önerdiği soruya yaptığı yorumu kontrol etmeye değer.
Shaun

3
değişmez bir sonuç isteniyorsa bunu yapmanın yolu budur. ToLookup değişmez.
Amit

1
Benim 2 sent (sadece 'çünkü beni bir saat için mücadele etti :)): bir özelliğe göre gruplandırırken, özellik bir değeri olduğundan emin olun! Aksi takdirde, Todict yöntemi anahtar oluşturmada başarısız olur (en azından String-Properties için ...) :)
dba

.GroupBy(o => o.PropertyName).ToDictionary(g => g.Key, g => g.ToList())Bu, Linq kütüphanesinin bir parçası olabilir. bu yüzden sadece yapmak zorundayız.ToDictionary(o=>o.PropertyName)
Jaider

3
Sadece değiştirin: @Jaider, zaten böyle işlevselliği yoktur ToDictionaryile ToLookup.
Robert Synoradzki

19

@Michael Blackburn hakkında yorum yapamam, ama sanırım bu oyunda GroupBy gerekli olmadığı için downvote var.

Gibi kullanın:

var lookupOfCustomObjects = listOfCustomObjects.ToLookup(o=>o.PropertyName);
var listWithAllCustomObjectsWithPropertyName = lookupOfCustomObjects[propertyName]

Ayrıca, bu performans GroupBy () kullanırken daha iyi bir şekilde gördüm.


Bir harf çevirisi yapıyordum, soruyu mümkün olan en iyi şekilde yanıtlamıyordum.
Michael Blackburn

1

@ Atari2600 için, lambda sözdiziminde ToLookup'u kullanmak şöyle bir yanıt olurdu:

var x = listOfCustomObjects
    .GroupBy(o => o.PropertyName)
    .ToLookup(customObject => customObject);

Temel olarak, IGrouping'i alır ve sizin için PropertyName değerleri anahtar olarak bir liste sözlüğü haline getirir.


Neden inişli çıkışlı? Bu doğru değil mi / soruyu cevaplıyor mu?
Michael Blackburn

1
Eğer kaçırırsanız, @RuudvK cevabında alt oyun GroupBy'nin gereksiz olduğundan şüphelendiğini belirtti. ToLookupişini yapacak aşırı yüklenme var.
Jeff B

Bu yanıtı kaçırdım, beni etiketlediğiniz için teşekkürler. Mantıksal olarak, Gruplama sözdizimsel olarak gereksizdir, sadece sorgu sözdiziminden yöntem sözdizimine geçişi daha net hale getirmek için bırakıyordum.
Michael Blackburn

GroupBy (yalnızca bir parametreyle aşırı yükleme), IEnumerable <IGrouping <TKey, TSource >> değerini izleyen ToLookup, bunu daha sonra IDL <TKey, IList <TSource>> IDL'sine benzemeyen oldukça karmaşık bir türe dönüştürür uygun türü döndürür.
xtofs

-1

Aşağıdakiler benim için çalıştı.

var temp = ctx.Set<DbTable>()
  .GroupBy(g => new { g.id })
  .ToDictionary(d => d.Key.id);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.