2009-06-09 17 views
19

चलें कहते हैं कि मैं इस काट Person वर्ग है:सी #: Enumerable.Aggregate विधि का उपयोग कैसे करें

class Person 
{ 
    public int Age { get; set; } 
    public string Country { get; set; } 

    public int SOReputation { get; set; } 
    public TimeSpan TimeSpentOnSO { get; set; } 

    ... 
} 

मैं तो कर सकते हैं Age और Country इस तरह पर समूह:

var groups = aListOfPeople.GroupBy(x => new { x.Country, x.Age }); 

तो मैं कर सकते हैं इस तरह की प्रतिष्ठा के साथ सभी समूहों को आउटपुट करें:

foreach(var g in groups) 
    Console.WriteLine("{0}, {1}:{2}", 
     g.Key.Country, 
     g.Key.Age, 
     g.Sum(x => x.SOReputation)); 

मेरा सवाल है, मैं TimeSpentOnSO संपत्ति का योग कैसे प्राप्त कर सकता हूं? Sum विधि इस मामले में काम नहीं करेगी क्योंकि यह केवल int और इसी तरह के लिए है। मैंने सोचा कि मैं Aggregate विधि का उपयोग कर सकता हूं, लेकिन केवल गंभीरता से यह नहीं समझ सकता कि इसका उपयोग कैसे किया जाए ... मैं विभिन्न संयोजनों में सभी प्रकार की गुणों और प्रकारों को आजमा रहा हूं लेकिन संकलक इसे पहचान नहीं पाएगा।

foreach(var g in groups) 
    Console.WriteLine("{0}, {1}:{2}", 
     g.Key.Country, 
     g.Key.Age, 
     g.Aggregate( what goes here?? )); 

क्या मैंने पूरी विधि को पूरी तरह से गलत समझा है? या क्या चल रहा है? क्या यह कुछ और तरीका है जिसका मुझे उपयोग करना चाहिए? या मुझे TimeSpan एस के लिए अपना खुद का Sum संस्करण लिखना है?

और गड़बड़ी में जोड़ने के लिए, क्या होगा यदि व्यक्ति एक अज्ञात वर्ग है, उदाहरण के लिए Select या GroupJoin कथन?


बस पता लगा है कि मैं Aggregate विधि काम कर सकता है अगर मैं TimeSpan संपत्ति पहले पर एक Select किया था ... लेकिन मैं कष्टप्रद उस तरह लगता है ... फिर भी मैं इस विधि को समझने नहीं लग रहा है बिल्कुल ...

foreach(var g in groups) 
    Console.WriteLine("{0}, {1}:{2}", 
     g.Key.Country, 
     g.Key.Age, 
     g.Select(x => x.TimeSpentOnSO) 
     g.Aggregate((sum, x) => sum + y)); 
+0

मैं सिर्फ यह इंगित करना चाहता हूं कि कुल (कम) दुनिया में सबसे अच्छी चीजों में से एक है जिसे मैंने चलाया है परिस्थितियों जहां मैं इसका उपयोग करना चाहता था। :) –

उत्तर

2

क्रिस और डेनियल जवाब का एक संयोजन मेरे लिए इसे हल। मुझे टाइमस्पेन शुरू करने की आवश्यकता थी, और मैंने गलत क्रम में चीजें कीं। समाधान है:

foreach(var g in groups) 
    Console.WriteLine("{0}, {1}:{2}", 
     g.Key.Country, 
     g.Key.Age, 
     g.Aggregate(TimeSpan.Zero, (sum, x) => sum + x.TimeSpentOnSO)); 

धन्यवाद!

और यह भी ... D'oh!

1

आप TimeSpanSum विधि ...

public static TimeSpan Sum(this IEnumerable<TimeSpan> times) 
{ 
    return TimeSpan.FromTicks(times.Sum(t => t.Ticks)); 
} 
public static TimeSpan Sum<TSource>(this IEnumerable<TSource> source, 
    Func<TSource, TimeSpan> selector) 
{ 
    return TimeSpan.FromTicks(source.Sum(t => selector(t).Ticks)); 
} 

वैकल्पिक रूप से, ०१२३८४७८७६ लिख सकता हैमें जेनेरिक-सक्षम Sum विधियां हैं, इसलिए Sum को TimeSpan पर ठीक काम करना चाहिए (क्योंकि TimeSpan+TimeSpan=>TimeSpan ऑपरेटर परिभाषित किया गया है)।

बस कृपया मुझे नंबर नहीं बताया ... यह मुझे डरा होगा ...

+0

हाँ, यह मेरा बैकअप पथ है। लेकिन मैं अभी भी यह जानना चाहूंगा कि यह विधि वास्तव में कैसे काम करती है। क्योंकि यह मुझे परेशान करता है कि मैं इसे सफलतापूर्वक उपयोग नहीं कर सकता: पी – Svish

+0

और हाँ, चलो उस नंबर को हमेशा के लिए गुप्त रखें। कभी भी एसओ: पी पर किसी तरह के आंकड़ों को पोस्ट करने के बारे में कभी भी सोचें (हालांकि मुझे यह कहना चाहिए कि मेरी जिज्ञासा की तरह यह चाहता है ... लेकिन इसे उस मामले में निजी रखें!) – Svish

23
List<TimeSpan> list = new List<TimeSpan> 
    { 
     new TimeSpan(1), 
     new TimeSpan(2), 
     new TimeSpan(3) 
    }; 

TimeSpan total = list.Aggregate(TimeSpan.Zero, (sum, value) => sum.Add(value)); 

Debug.Assert(total.Ticks == 6); 
+0

टाइमस्पेन.जेरो के साथ आरंभ करें। बहुत अच्छा मुद्दा। यह टाइमस्पैन की एक सूची के साथ था, हालांकि, मुझे टाइमस्पेन संपत्ति के साथ किसी और चीज की एक सूची की आवश्यकता थी। लेकिन मैंने इसे समझ लिया। धन्यवाद! – Svish

14
g.Aggregate(TimeSpan.Zero, (i, p) => i + p.TimeSpentOnSO) 

असल में, सकल करने के लिए पहला तर्क एक प्रारंभकर्ता है, जो के रूप में इस्तेमाल किया जाता है समारोह में "i" का पहला मान दूसरे तर्क में पारित किया गया। यह सूची में फिर से शुरू होगा, और हर बार, "मैं" अब तक कुल शामिल होगा।

उदाहरण के लिए:

List<int> nums = new List<int>{1,2,3,4,5}; 

nums.Aggregate(0, (x,y) => x + y); // sums up the numbers, starting with 0 => 15 
nums.Aggregate(0, (x,y) => x * y); // multiplies the numbers, starting with 0 => 0, because anything multiplied by 0 is 0 
nums.Aggregate(1, (x,y) => x * y); // multiplies the numbers, starting with 1 => 120 
+0

यह स्याही के साथ था, जिसे मैंने पहले ही हल किया था। लेकिन इसे शुरू करने के तरीके को साफ़ करने के लिए धन्यवाद! – Svish

+0

क्षमा करें यह मूल रूप से इन्ट्स का उपयोग कर रहा था। मैंने सवाल को गलत तरीके से पढ़ा, लेकिन यह आपके लिए काम करना चाहिए, साथ ही यह समझाएगा कि सामान्य रूप से कुल कैसे काम करता है। –

0

आप समयावधि की कुल संपत्ति में से एक पर योग कर सकता है। उदाहरण के लिए, आप हो सकता है समय की प्रतिनिधित्व किया TotalHours पर खर्च अतः इस तरह:

g.Sum(x => x.SOReputation.TotalHours) 

मेरा मानना ​​है कि यह आप परिणाम आप देख रहे हैं देना होगा, लेकिन चेतावनी के साथ आगे रहने के लिए होगा कि आपको जो चाहिए (माप, मिनट, दूसरा, दिन इत्यादि) के अनुसार माप की इकाइयां

+0

दरअसल मैं यही कर रहा हूं, लेकिन अन्य कारणों से। अभी भी खुश है कि मैं अंततः समग्र विधि को समझता हूं (हालांकि एक विशेषज्ञ नहीं: पी)। – Svish

संबंधित मुद्दे