Cách nhận giá trị từ IGrouping


210

Tôi có một câu hỏi về IGroupingSelect()phương pháp.

Hãy nói rằng tôi đã có một IEnumerable<IGrouping<int, smth>>cách này:

var groups = list.GroupBy(x => x.ID);

nơi listlà một List<smth>.

Và bây giờ tôi cần chuyển các giá trị của từng loại IGroupingsang danh sách khác theo một cách nào đó:

foreach (var v in structure)
{
    v.ListOfSmth = groups.Select(...); // <- ???
}

Bất cứ ai có thể đề nghị làm thế nào để có được các giá trị ( List<smth>) từ một IGrouping<int, smth>trong bối cảnh như vậy?


ID thường là một trường danh tính nên là duy nhất, điều này sẽ khiến việc nhóm của nó trở nên vô dụng, nếu bạn chỉ cố gắng xóa dữ liệu trùng lặp, hãy thử Phân biệt () thay vào đó. nếu đó là list.groupBy (x => x.SubID) thì sẽ hợp lý khi sử dụng nhóm nhưng trong trường hợp đó bạn rất có thể muốn giữ nhóm và foreach (var grp theo nhóm) {grp.ToList () ; } sẽ làm điều đó
MikeT

Câu trả lời:


277

Kể từ khi IGrouping<TKey, TElement>thực hiện IEnumerable<TElement>, bạn có thể sử dụng SelectManyđể đặt tất cả các IEnumerablesmặt sau lại IEnumerablevới nhau:

List<smth> list = new List<smth>();
IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.id);
IEnumerable<smth> smths = groups.SelectMany(group => group);
List<smth> newList = smths.ToList();

3
Không phải nó giống như một "orderBy" bình thường sao? Danh sách <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ

@MorgoZ, câu hỏi là về việc lấy groupsvà quay lại danh sách phẳng.
Matt Smith

3
@MorgoZ, OrderBy(x => x.id)sẽ sắp xếp chúng theo thứ tự tăng dần theo ID. Tương phản điều này với .GroupBy(x => x.id).SelectMany(group => group), sẽ sắp xếp chúng theo thứ tự xuất hiện đầu tiên của ID. Nếu ID gốc theo thứ tự: [1,3,2,2,2,3,0], sau đó nhóm chúng lại và sau đó làm phẳng thành một danh sách sẽ đặt ID theo thứ tự mới: [1,3,3, 2,2,2,0].
Pi Fisher

2
Nó không hoạt động đối với tôi .. nó nói rằng loại không thể được suy ra theo cách sử dụng
Revious 15/12/17

3
loại không thể được suy luận theo cách sử dụng
Leo Gurdian

34
foreach (var v in structure) 
{     
    var group = groups.Single(g => g.Key == v. ??? );
    v.ListOfSmth = group.ToList();
}

Đầu tiên bạn cần chọn nhóm mong muốn. Sau đó, bạn có thể sử dụng ToListphương pháp của nhóm. Đây IGroupinglà một IEnumerabletrong những giá trị.


17

Phiên bản làm rõ hơn của các câu trả lời trên:

IEnumerable<IGrouping<int, ClassA>> groups = list.GroupBy(x => x.PropertyIntOfClassA);

foreach (var groupingByClassA in groups)
{
    int propertyIntOfClassA = groupingByClassA.Key;

    //iterating through values
    foreach (var classA in groupingByClassA)
    {
        int key = classA.PropertyIntOfClassA;
    }
}

Tôi không nghĩ vậy, ít nhất là bây giờ.
snr

15

Từ định nghĩa của IGrouping:

IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable

bạn chỉ có thể lặp qua các yếu tố như thế này:

IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.ID)
foreach(IEnumerable<smth> element in groups)
{
//do something
}

1
mà lặp đi lặp lại thông qua anh ấy nhóm không phải là các mục trong nhóm
MikeT

1
Ôi, lỗi của tôi, sau đó: 'foreach (smth p in Groups.SelectMany (sth => sth))'
user1275513
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.