समूह और गिनती के साथ LINQ


222

यह बहुत आसान है, लेकिन मैं नुकसान में हूं: इस प्रकार के डेटा सेट को देखते हुए:

UserInfo(name, metric, day, other_metric)

और यह नमूना डेटा सेट:

joe  1 01/01/2011 5
jane 0 01/02/2011 9
john 2 01/03/2011 0
jim  3 01/04/2011 1
jean 1 01/05/2011 3
jill 2 01/06/2011 5
jeb  0 01/07/2011 3
jenn 0 01/08/2011 7

मैं उस तालिका को पुनः प्राप्त करना चाहूंगा जो क्रम में कुल संख्या के साथ मैट्रिक्स को सूचीबद्ध करती है (0,1,2,3 ..) जो गिनती होती है। तो इस सेट से आप के साथ समाप्त होगा:

0 3    
1 2    
2 2    
3 1

मैं LINQ सिंटैक्स के साथ जूझ रहा हूं, लेकिन मैं इस बात पर अड़ा हुआ हूं कि एक ग्रुपबी और काउंट कहां रखा जाए .... कोई मदद?

पोस्ट संपादित करें: मैं काम करने के लिए पोस्ट किए गए उत्तरों को प्राप्त करने में सक्षम नहीं था क्योंकि वे हमेशा अलग-अलग गणनाओं की संख्या के साथ एक रिकॉर्ड लौटाते थे। हालाँकि, मैं एक LINQ को SQL उदाहरण के लिए एक साथ रखने में सक्षम था जिसने काम किया:

        var pl = from r in info
                 orderby r.metric    
                 group r by r.metric into grp
                 select new { key = grp.Key, cnt = grp.Count()};

इस परिणाम ने मुझे 'मैट्रिक्स' और प्रत्येक के साथ जुड़े उपयोगकर्ताओं की संख्या के साथ रिकॉर्ड का एक निर्धारित सेट दिया। मैं सामान्य रूप से LINQ के लिए स्पष्ट रूप से नया हूँ और मेरी अप्रशिक्षित आँख के लिए यह दृष्टिकोण शुद्ध LINQ दृष्टिकोण के समान है, फिर भी मुझे एक अलग उत्तर दिया।


हां, मेरे पास है, लेकिन जिमी के स्पष्टीकरण ने मुझे और अधिक मदद की। हालांकि मैं काम करने के लिए कभी भी उनका उदाहरण नहीं ले पाया लेकिन इसने मुझे एक नई दिशा में ले गया।
जियो

@ जिमी ने मानक LINQ क्वेरी सिंटैक्स के बजाय LINQ अभिव्यक्तियों के लिए कार्यात्मक वाक्यविन्यास का उपयोग किया, साथ ही उन्होंने विलंबित निष्पादन प्रारूप के बजाय उन कार्यों के तत्काल निष्पादन को दिखाने का फैसला किया। एक नए व्यक्ति के लिए जो भ्रामक होगा। पता नहीं उसने ऐसा क्यों किया।
रिचर्ड रॉबर्टसन

जवाबों:


396

कॉल करने के बाद GroupBy, आपको समूहों की एक श्रृंखला मिलती है IEnumerable<Grouping>, जहाँ प्रत्येक समूह अपने आप Keyमें समूह बनाने के लिए उपयोग की जाने वाली IEnumerable<T>चीज़ों को उजागर करता है और यह भी कि आपके मूल डेटा सेट में जो भी चीज़ें हैं, उनमें से एक है। आपको केवल Count()उप-समूह को प्राप्त करने के लिए उस समूहीकरण पर कॉल करना होगा।

foreach(var line in data.GroupBy(info => info.metric)
                        .Select(group => new { 
                             Metric = group.Key, 
                             Count = group.Count() 
                        })
                        .OrderBy(x => x.Metric)
{
     Console.WriteLine("{0} {1}", line.Metric, line.Count);
}


यह एक शानदार त्वरित उत्तर था, लेकिन मुझे पहली पंक्ति के साथ एक समस्या हो रही है, विशेष रूप से "data.groupby (जानकारी => info.metric)"

मुझे लगता है कि आपके पास पहले से ही कुछ की एक सूची / सरणी है classजो दिखता है

class UserInfo {
    string name;
    int metric;
    ..etc..
} 
...
List<UserInfo> data = ..... ;

जब आप ऐसा करते हैं data.GroupBy(x => x.metric), तो इसका अर्थ है " xIEnumerable में प्रत्येक तत्व के लिए इसे परिभाषित करें data, इसकी गणना करें .metric, फिर सभी तत्वों को एक ही मीट्रिक के साथ समूह में एक Groupingऔर IEnumerableसभी परिणामी समूहों में से एक को लौटाएं । आपके उदाहरण डेटा सेट को देखते हुए।

    <DATA>           | Grouping Key (x=>x.metric) |
joe  1 01/01/2011 5  | 1
jane 0 01/02/2011 9  | 0
john 2 01/03/2011 0  | 2
jim  3 01/04/2011 1  | 3
jean 1 01/05/2011 3  | 1
jill 2 01/06/2011 5  | 2
jeb  0 01/07/2011 3  | 0
jenn 0 01/08/2011 7  | 0

यह ग्रुपबी के बाद निम्न परिणाम देगा:

(Group 1): [joe  1 01/01/2011 5, jean 1 01/05/2011 3]
(Group 0): [jane 0 01/02/2011 9, jeb  0 01/07/2011 3, jenn 0 01/08/2011 7]
(Group 2): [john 2 01/03/2011 0, jill 2 01/06/2011 5]
(Group 3): [jim  3 01/04/2011 1]

यह एक शानदार त्वरित उत्तर था, लेकिन मुझे पहली पंक्ति के साथ एक समस्या हो रही है, विशेष रूप से "data.groupby (जानकारी => info.metric)"। सादा 'डेटा' वर्तमान में डेटा सेट है, लेकिन क्या 'info.metric' रिपीट है? वर्ग की परिभाषा?
Gio

"info.metric" आपके प्रश्न में उल्लिखित UserInfo वर्ग पर मीट्रिक संपत्ति / क्षेत्र होगा।
ली-एम।

1
धन्यवाद कि पता चला, लेकिन वास्तव में यह मुझे एक ही मूल्य देता प्रतीत होता है - अर्थात् विभिन्न मीट्रिक गिनती की कुल संख्या। इस उदाहरण में मुझे "मेट्रिक्स 4" मिलता है जो बताता है कि मेरे पास कितने अलग-अलग मायने हैं।
जियो

1
वाह। आपने पूरी तरह से समूहन समझाया !! यह अकेला ही पोस्ट के लायक था .... मुझे लगता है कि "मेट्रिक्स 4" का परिणाम मिल गया, लेकिन धन्यवाद!
जियो

4
इस उत्तर की शुरुआत, "GroupBy को कॉल करने के बाद, आपको समूह की एक श्रृंखला मिलती है IEnumerable <Grouping>, जहां प्रत्येक Grouping स्वयं समूह बनाने के लिए उपयोग की जाने वाली कुंजी को उजागर करता है और आपके मूल डेटा में जो भी आइटम हैं उनका IEnumerable <T> है सेट ", LINQ GroupBy का सबसे स्पष्ट स्पष्टीकरण मैंने अभी तक पढ़ा है, धन्यवाद।
dumbledad

48

मान लिया गया userInfoListहै List<UserInfo>:

        var groups = userInfoList
            .GroupBy(n => n.metric)
            .Select(n => new
            {
                MetricName = n.Key,
                MetricCount = n.Count()
            }
            )
            .OrderBy(n => n.MetricName);

लैम्बडा फ़ंक्शन के लिए GroupBy(), n => n.metricइसका अर्थ है कि यह सामने आई metricप्रत्येक UserInfoवस्तु से फ़ील्ड प्राप्त करेगा । प्रकार का nसंदर्भ के आधार पर होता है, पहली घटना में यह प्रकार का होता है UserInfo, क्योंकि सूची में UserInfoऑब्जेक्ट होते हैं। दूसरी घटना nमें प्रकार की है Grouping, क्योंकि अब यह Groupingवस्तुओं की एक सूची है ।

Groupingजैसे विस्तार के तरीके हैं .Count(), .Key()और बहुत कुछ और भी जो आप उम्मीद करेंगे। जैसे आप .Lenghtएक पर जाँचेंगे string, आप .Count()एक समूह पर जाँच कर सकते हैं ।


23
userInfos.GroupBy(userInfo => userInfo.metric)
        .OrderBy(group => group.Key)
        .Select(group => Tuple.Create(group.Key, group.Count()));

1
छोटा टाइपो -> group.keyइन द सेलेक्ट (...) होना चाहिएgroup.Key
Jan
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.