วิธีรับค่าจาก IGrouping


211

ฉันมีคำถามเกี่ยวกับIGroupingและSelect()วิธีการ

สมมติว่าฉันมีIEnumerable<IGrouping<int, smth>>วิธีนี้:

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

ที่เป็นlistList<smth>

และตอนนี้ฉันต้องส่งค่าของแต่ละIGroupingรายการไปยังรายการอื่นด้วยวิธีใดวิธีหนึ่ง:

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

ใครช่วยแนะนำวิธีการรับค่า ( List<smth>) จากIGrouping<int, smth>ในบริบทดังกล่าว?


ID มักจะเป็นช่องข้อมูลประจำตัวซึ่งควรจะไม่ซ้ำกันซึ่งจะทำให้การจัดกลุ่มโดยไม่มีประโยชน์ถ้าคุณเพียงแค่พยายามลบข้อมูลที่ซ้ำกันลอง Distinct () แทน ถ้าเป็น list.GroupBy (x => x.SubID) มันจะสมเหตุสมผลที่จะใช้การจัดกลุ่ม แต่ในกรณีนั้นคุณน่าจะต้องการจัดกลุ่มและ foreach (var grp ในกลุ่ม) {grp.ToList () ; } จะทำเช่นนั้น
MikeT

คำตอบ:


277

ตั้งแต่IGrouping<TKey, TElement>การดำเนินการIEnumerable<TElement>คุณสามารถใช้SelectManyเพื่อรวมIEnumerablesด้านหลังIEnumerableทั้งหมดเข้าด้วยกัน:

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
ไม่เหมือนกับคำสั่ง "ปกติโดย" ใช่หรือไม่ รายการ <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ

@ MorgoZ คำถามคือเกี่ยวกับการgroupsและกลับไปที่รายการแบน
Matt Smith

3
@ MorgoZ OrderBy(x => x.id)จะเรียงลำดับตาม ID จากน้อยไปหามาก ตัดกันด้วย.GroupBy(x => x.id).SelectMany(group => group)ซึ่งจะเรียงลำดับตามการปรากฏตัวครั้งแรกของ ID หากรหัสต้นฉบับอยู่ในลำดับ: [1,3,2,2,2,2,3,0] จากนั้นจัดกลุ่มรหัสแล้วแบนลงในรายการเดียวจะทำให้ ID อยู่ในลำดับใหม่: [1,3,3, 2,2,2,0]
Pi Fisher

2
มันใช้งานไม่ได้สำหรับฉัน .. มันบอกว่าประเภทไม่สามารถอนุมานได้จากการใช้งาน
Revious

3
ไม่สามารถอนุมานประเภทได้โดยการใช้งาน
Leo Gurdian

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

ก่อนอื่นคุณต้องเลือกกลุ่มที่ต้องการ จากนั้นคุณสามารถใช้ToListวิธีการในกลุ่ม IGroupingเป็นIEnumerableของค่า


17

คำอธิบายข้างต้นรุ่นที่มีความชัดเจนมากขึ้น:

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

ฉันไม่คิดอย่างนั้นอย่างน้อยตอนนี้
snr

15

จากคำจำกัดความของ IGrouping:

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

คุณสามารถทำซ้ำองค์ประกอบต่างๆดังนี้:

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

1
วนซ้ำที่เขาไม่ได้รวมไว้ในกลุ่ม
MikeT

1
โอ้ความผิดพลาดของฉันจากนั้น: 'foreach (smth p ในกลุ่ม SelectMany (sth => sth))'
user1275513
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.