c# - LINQ में समूह




group-by (5)

मान लीजिए कि हमारे पास एक वर्ग है या नहीं

class Person { 
    internal int PersonID; 
    internal string car  ; 
}

अब मेरे पास इस वर्ग की एक सूची है: List<Person> persons;

अब इस सूची में एक ही व्यक्ति आईडी के साथ कई उदाहरण हो सकते हैं, उदाहरण के लिए:

persons[0] = new Person { PersonID = 1, car = "Ferrari" }; 
persons[1] = new Person { PersonID = 1, car = "BMW"     }; 
persons[2] = new Person { PersonID = 2, car = "Audi"    }; 

क्या कोई तरीका है personID मैं personID द्वारा personID कर सकता personID और उसके पास सभी कारों की सूची प्राप्त कर सकता हूं?

उदाहरण के लिए, अपेक्षित परिणाम होगा

class Result { 
   int PersonID;
   List<string> cars; 
}

तो समूह के बाद, मुझे मिल जाएगा:

results[0].PersonID = 1; 
List<string> cars = results[0].cars; 

result[1].PersonID = 2; 
List<string> cars = result[1].cars;

मैंने अभी तक जो किया है उससे:

var results = from p in persons
              group p by p.PersonID into g
              select new { PersonID = g.Key, // this is where I am not sure what to do

क्या कोई मुझे सही दिशा में इंगित कर सकता है?


आप यह भी कोशिश कर सकते हैं।

var results= persons.GroupBy(n => new { n.PersonId, n.car})
                .Select(g => new {
                               g.Key.PersonId,
                               g.Key.car)}).ToList();

इसे इस्तेमाल करे :

var results= persons.GroupBy(n => n.PersonId)
            .Select(g => new {
                           PersonId=g.Key,
                           Cars=g.Select(p=>p.car).ToList())}).ToList();

लेकिन प्रदर्शन के अनुसार निम्नलिखित अभ्यास बेहतर है और स्मृति उपयोग में अधिक अनुकूलित (जब हमारे सरणी में लाखों की तरह अधिक आइटम होते हैं):

var carDic=new Dictionary<int,List<string>>();
for(int i=0;i<persons.length;i++)
{
   var person=persons[i];
   if(carDic.ContainsKey(person.PersonId))
   {
        carDic[person.PersonId].Add(person.car);
   }
   else
   {
        carDic[person.PersonId]=new List<string>(){person.car};
   }
}
//returns the list of cars for PersonId 1
var carList=carDic[1];

बिल्कुल - आप मूल रूप से चाहते हैं:

var results = from p in persons
              group p.car by p.PersonId into g
              select new { PersonId = g.Key, Cars = g.ToList() };

या एक गैर-क्वेरी अभिव्यक्ति के रूप में:

var results = persons.GroupBy(
    p => p.PersonId, 
    p => p.car,
    (key, g) => new { PersonId = key, Cars = g.ToList() });

मूल रूप से समूह की सामग्री (जब एक IEnumerable<T> रूप में देखें) प्रक्षेपण (इस मामले में p.car ) में दिए गए कुंजी के लिए मौजूद किसी भी मूल्य का अनुक्रम है।

GroupBy कैसे काम करता है, इस बारे में अधिक जानकारी के लिए, विषय पर मेरी एडुलिनक पोस्ट देखें।

(मैंने उपरोक्त में PersonId PersonID का नाम बदल दिया है, .NET नामकरण सम्मेलनों का पालन करने के लिए।)

वैकल्पिक रूप से, आप एक Lookup उपयोग कर सकते हैं:

var carsByPersonId = persons.ToLookup(p => p.PersonId, p => p.car);

फिर आप प्रत्येक व्यक्ति के लिए कार आसानी से प्राप्त कर सकते हैं:

// This will be an empty sequence for any personId not in the lookup
var carsForPerson = carsByPersonId[personId];

मैंने क्वेरी सिंटेक्स और विधि सिंटेक्स के साथ एक वर्किंग कोड नमूना बनाया है। मुझे आशा है कि यह दूसरों की मदद करे :)

आप यहां नेट नेटल पर भी कोड चला सकते हैं:

using System;
using System.Linq;
using System.Collections.Generic;

class Person
{ 
    public int PersonId; 
    public string car  ; 
}

class Result
{ 
   public int PersonId;
   public List<string> Cars; 
}

public class Program
{
    public static void Main()
    {
        List<Person> persons = new List<Person>()
        {
            new Person { PersonId = 1, car = "Ferrari" },
            new Person { PersonId = 1, car = "BMW" },
            new Person { PersonId = 2, car = "Audi"}
        };

        //With Query Syntax

        List<Result> results1 = (
            from p in persons
            group p by p.PersonId into g
            select new Result()
                {
                    PersonId = g.Key, 
                    Cars = g.Select(c => c.car).ToList()
                }
            ).ToList();

        foreach (Result item in results1)
        {
            Console.WriteLine(item.PersonId);
            foreach(string car in item.Cars)
            {
                Console.WriteLine(car);
            }
        }

        Console.WriteLine("-----------");

        //Method Syntax

        List<Result> results2 = persons
            .GroupBy(p => p.PersonId, 
                     (k, c) => new Result()
                             {
                                 PersonId = k,
                                 Cars = c.Select(cs => cs.car).ToList()
                             }
                    ).ToList();

        foreach (Result item in results2)
        {
            Console.WriteLine(item.PersonId);
            foreach(string car in item.Cars)
            {
                Console.WriteLine(car);
            }
        }
    }
}

परिणाम यहां दिया गया है:

1
Ferrari
BMW
2
Audi
-----------
1
Ferrari
BMW
2
Audi


var results = from p in persons
              group p by p.PersonID into g
              select new { PersonID = g.Key, Cars = g.Select(m => m.car) };






group-by