LINQ अलग एल्गोरिथ्म समझाया


721

यह लंगड़ा लग सकता है, लेकिन मैं वास्तव में अच्छी व्याख्या नहीं कर पाया हूं Aggregate

छोटे और स्पष्ट उदाहरण के साथ अच्छा संक्षिप्त, वर्णनात्मक, व्यापक है।

जवाबों:


1015

सबसे आसान समझने वाली परिभाषा Aggregateयह है कि यह सूची के प्रत्येक तत्व पर एक ऑपरेशन करता है जो पहले किए गए संचालन को ध्यान में रखता है। यह कहना है कि यह पहले और दूसरे तत्व पर कार्रवाई करता है और परिणाम को आगे बढ़ाता है। फिर यह पिछले परिणाम और तीसरे तत्व पर काम करता है और आगे बढ़ता है। आदि।

उदाहरण 1. संख्याओं का योग

var nums = new[]{1,2,3,4};
var sum = nums.Aggregate( (a,b) => a + b);
Console.WriteLine(sum); // output: 10 (1+2+3+4)

यह जोड़ता है 1और 2बनाने के लिए 3। फिर जोड़ता है 3(पिछले का परिणाम) और 3(अनुक्रम में अगला तत्व) बनाने के लिए 6। फिर जोड़ता है 6और 4बनाने के लिए 10

उदाहरण 2. स्ट्रिंग की एक सरणी से एक सीएसवी बनाएं

var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate( (a,b) => a + ',' + b);
Console.WriteLine(csv); // Output a,b,c,d

यह उसी तरह से काम करता है। कॉम्पटेट को aएक कॉमा और bबनाने के लिए a,b। फिर a,b कॉमा के साथ और cबनाने के लिए a,b,c। और इसी तरह।

उदाहरण 3. एक बीज का उपयोग करके संख्याओं को गुणा करना

पूर्णता के लिए, एक अधिभार होता है Aggregateजिसमें बीज का मूल्य होता है।

var multipliers = new []{10,20,30,40};
var multiplied = multipliers.Aggregate(5, (a,b) => a * b);
Console.WriteLine(multiplied); //Output 1200000 ((((5*10)*20)*30)*40)

बहुत ऊपर के उदाहरण, के एक मूल्य के साथ इस तरह शुरू होता है 5अनुक्रम के पहले तत्व द्वारा और यह पलता 10का एक परिणाम दे रही है 50। इस परिणाम को आगे बढ़ाया जाता है और 20परिणाम देने के लिए अगले क्रम से गुणा किया जाता है 1000। यह अनुक्रम के शेष 2 तत्व के माध्यम से जारी है।

लाइव उदाहरण: http://rextester.com/ZXZ64749
डॉक्स: http://msdn.microsoft.com/en-us/library/bb548651.aspx


परिशिष्ट

उदाहरण 2, ऊपर, अल्पविराम द्वारा अलग किए गए मानों की सूची बनाने के लिए स्ट्रिंग संघनन का उपयोग करता है। यह एक सरलीकृत तरीका है Aggregateजिसके उपयोग की व्याख्या करना इस उत्तर का उद्देश्य था। हालांकि, अगर इस तकनीक का उपयोग वास्तव में अल्पविराम से अलग किए गए डेटा की एक बड़ी मात्रा में बनाने के लिए किया जाता है, तो ए का उपयोग करना अधिक उचित होगा StringBuilder, और यह Aggregateआरंभ करने के लिए वरीयता प्राप्त अधिभार का उपयोग करने के साथ पूरी तरह से संगत है StringBuilder

var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate(new StringBuilder(), (a,b) => {
    if(a.Length>0)
        a.Append(",");
    a.Append(b);
    return a;
});
Console.WriteLine(csv);

अपडेट किया गया उदाहरण: http://rextester.com/YZCVXV6464


11
पहले विवरण के लिए एक और स्पष्टीकरण यह है कि आप जो फ़ंक्शन प्रदान करते हैं, वह हमेशा पहले दो सदस्यों को जोड़ता है जब तक कि एक तत्व को छोटा नहीं किया जाता है। तो [1,2,3,4]हो जाएगा [3,3,4]तो [6,4]और पिछले पर [10]। लेकिन एकल मूल्य की एक सरणी वापस करने के बजाय आपको केवल मूल्य ही मिलता है।
डेविड राब

2
क्या मैं किसी एग्रीगेट फंक्शन से जल्दी ब्रेक / एग्जिट कर सकता हूं? उदाहरण के लिए, chars.Aggregate ((a, b) => {if (a == 'a') पूरे एग्रीगेट को तोड़ दें + +, '+ b})
Jeff Tian

13
@ जेफ़ियन - मेरा सुझाव है कि TakeWhileतब Aggregateअ-ज्वलनशील एक्सटेंशन के बीटूट को चेज़ किया जाएगा - वे आसानी से चेनेबल होते हैं। तो आप के साथ अंत TakeWhile(a => a == 'a').Aggregate(....)। इस उदाहरण को देखें: rextester.com/WPRA60543
Jamiec

2
परिशिष्ट पर एक विचार के रूप में, पूरे ब्लॉक को आसानी से प्रतिस्थापित किया जा सकता है var csv = string.Join(",", chars)(कुल या स्ट्रिंगर की कोई आवश्यकता नहीं) - लेकिन हाँ, मुझे पता है कि उत्तर का उदाहरण कुल मिलाकर उपयोग का उदाहरण देना था, इसलिए यह अच्छा है। लेकिन मैं अभी भी यह उल्लेख करना चाहता था कि यह केवल तार से जुड़ने के लिए अनुशंसित नहीं है, इसके लिए पहले से ही एक विधि समर्पित है ....
T_D

2
एक और आम उपयोग (अभी तक केवल मैंने भी उत्पादन कोड में देखा है) न्यूनतम या अधिकतम आइटम प्राप्त करना है जैसेvar biggestAccount = Accounts.Aggregate((a1, a2) => a1.Amount >= a2.Amount ? a1 : a2);
फ्रेंक

133

यह आंशिक रूप से निर्भर करता है कि आप किस अधिभार के बारे में बात कर रहे हैं, लेकिन मूल विचार यह है:

  • एक बीज से "वर्तमान मूल्य" के रूप में शुरू करें
  • अनुक्रम पर फेरबदल। अनुक्रम में प्रत्येक मूल्य के लिए:
    • (currentValue, sequenceValue)में बदलने के लिए एक उपयोगकर्ता-निर्दिष्ट फ़ंक्शन लागू करें(nextValue)
    • सेट currentValue = nextValue
  • फाइनल लौटाओ currentValue

आपको Aggregateमेरी एडलिनक श्रृंखला में पद उपयोगी मिल सकता है - इसमें एक अधिक विस्तृत विवरण (विभिन्न अधिभार सहित) और कार्यान्वयन शामिल हैं।

एक सरल उदाहरण इसके Aggregateविकल्प के रूप में उपयोग कर रहा है Count:

// 0 is the seed, and for each item, we effectively increment the current value.
// In this case we can ignore "item" itself.
int count = sequence.Aggregate(0, (current, item) => current + 1);

या शायद स्ट्रिंग्स के एक क्रम में तार की सभी लंबाई को सम्‍मिलित करें:

int total = sequence.Aggregate(0, (current, item) => current + item.Length);

व्यक्तिगत रूप से मुझे शायद ही कभीAggregate उपयोगी लगता है - "सिलवाया" एकत्रीकरण विधियां आमतौर पर मेरे लिए पर्याप्त हैं।


6
@ क्या एग्रीगेट के अतुल्यकालिक रूपांतर हैं जो वस्तुओं को एक पेड़ में विभाजित करते हैं ताकि काम को कोर के बीच विभाजित किया जा सके? ऐसा लगता है कि विधि का डिज़ाइन "कम" या "गुना" की अवधारणाओं के अनुरूप है, लेकिन मुझे नहीं पता है कि क्या यह वास्तव में ऐसा हो रहा है जो हुड के नीचे है, या बस मदों की सूची के माध्यम से पुनरावृत्ति कर रहा है।
एरोनल्स

@Jon: ऊपर उल्लिखित edulink काम नहीं कर रही है क्या आप मुझे सही लिंक पर पुनर्निर्देशित कर सकते हैं। और क्या आप शब्द "सिलवाया" एकत्रीकरण कार्यों के बारे में अधिक विशिष्ट हो सकते हैं जो आपने अपने उत्तर में उपयोग किया था।
कौशिक

1
@ कौशिक: मैंने पोस्ट में लिंक को ठीक कर दिया है। "सिलवाया" एकत्रीकरण कार्यों से मेरा मतलब मैक्स / मिन / काउंट / सम जैसी चीजों से है।
जॉन स्कीट

62

सुपर शॉर्ट एग्रीगेट, हास्केल / एमएल / एफ # में गुना की तरह काम करता है।

थोड़ा अधिक लंबा । मोम (), .Min (), .Sum (), .Aiture () सभी एक क्रम में तत्वों पर पुनरावृत्त करता है और संबंधित समुच्चय फ़ंक्शन का उपयोग करके उन्हें एकत्र करता है। .Agregate () सामान्यीकृत एग्रीगेटर है जिसमें यह डेवलपर को स्टार्ट स्टेट (उर्फ बीज) और एग्रीगेट फ़ंक्शन को निर्दिष्ट करने की अनुमति देता है।

मुझे पता है कि आपने एक छोटी व्याख्या के लिए कहा था, लेकिन मुझे लगा कि अन्य लोगों ने कुछ छोटे जवाब दिए हैं, मुझे लगा कि आप शायद थोड़ी देर में दिलचस्पी लेंगे

कोड के साथ लंबा संस्करण एक तरीका है जो यह बताता है कि यह दिखाया जा सकता है कि कैसे आप नमूना मानक विचलन लागू करते हैं एक बार फ़ॉर्च का उपयोग करते हुए और एक बार उपयोग करते हैं। नोट: मैंने यहां प्रदर्शन को प्राथमिकता नहीं दी है, इसलिए मैं अनावश्यक रूप से कोलीसिटॉन पर कई बार पुनरावृति करता हूं

पहले द्विघात दूरी का योग बनाने के लिए उपयोग किया जाने वाला एक सहायक कार्य:

static double SumOfQuadraticDistance (double average, int value, double state)
{
    var diff = (value - average);
    return state + diff * diff;
}

तब ForEach का उपयोग करके नमूना मानक विचलन:

static double SampleStandardDeviation_ForEach (
    this IEnumerable<int> ints)
{
    var length = ints.Count ();
    if (length < 2)
    {
        return 0.0;
    }

    const double seed = 0.0;
    var average = ints.Average ();

    var state = seed;
    foreach (var value in ints)
    {
        state = SumOfQuadraticDistance (average, value, state);
    }
    var sumOfQuadraticDistance = state;

    return Math.Sqrt (sumOfQuadraticDistance / (length - 1));
}

फिर एक बार उपयोग करें।

static double SampleStandardDeviation_Aggregate (
    this IEnumerable<int> ints)
{
    var length = ints.Count ();
    if (length < 2)
    {
        return 0.0;
    }

    const double seed = 0.0;
    var average = ints.Average ();

    var sumOfQuadraticDistance = ints
        .Aggregate (
            seed,
            (state, value) => SumOfQuadraticDistance (average, value, state)
            );

    return Math.Sqrt (sumOfQuadraticDistance / (length - 1));
}

ध्यान दें कि ये फ़ंक्शन समान हैं सिवाय इसके कि कैसे sumOfQuadraticDistance की गणना की जाती है:

var state = seed;
foreach (var value in ints)
{
    state = SumOfQuadraticDistance (average, value, state);
}
var sumOfQuadraticDistance = state;

बनाम:

var sumOfQuadraticDistance = ints
    .Aggregate (
        seed,
        (state, value) => SumOfQuadraticDistance (average, value, state)
        );

तो क्या है। एग्रीगेट यह है कि यह इस एग्रीगेटर पैटर्न को एनकैप्सुलेट करता है और मुझे उम्मीद है कि एएग्रीगेट का कार्यान्वयन कुछ इस तरह दिखाई देगा:

public static TAggregate Aggregate<TAggregate, TValue> (
    this IEnumerable<TValue> values,
    TAggregate seed,
    Func<TAggregate, TValue, TAggregate> aggregator
    )
{
    var state = seed;

    foreach (var value in values)
    {
        state = aggregator (state, value);
    }

    return state;
}

मानक विचलन कार्यों का उपयोग कुछ इस तरह होगा:

var ints = new[] {3, 1, 4, 1, 5, 9, 2, 6, 5, 4};
var average = ints.Average ();
var sampleStandardDeviation = ints.SampleStandardDeviation_Aggregate ();
var sampleStandardDeviation2 = ints.SampleStandardDeviation_ForEach ();

Console.WriteLine (average);
Console.WriteLine (sampleStandardDeviation);
Console.WriteLine (sampleStandardDeviation2);

IMHO

तो करता है। पढ़ने में मदद करने के लिए पर्याप्त मदद? सामान्य तौर पर मैं LINQ से प्यार करता हूँ क्योंकि मुझे लगता है। जहाँ, .Select, .OrderBy और इतने पर पठनीयता में मदद मिलती है (यदि आप इनबिल्ड हाइपरहिकल से बचते हैं। चुनाव)। समग्रता के लिए एग्रीगेट को लिनाक में होना चाहिए लेकिन व्यक्तिगत रूप से मैं इतना आश्वस्त नहीं हूं कि। अच्छी तरह से लिखे गए फॉर्च्यूनर की तुलना में एग्रीगेट पठनीयता जोड़ता है।


+1 उत्कृष्ट! लेकिन विस्तार के तरीके SampleStandardDeviation_Aggregate()और (एक्सेस क्वालिफायर के अभाव में डिफ़ॉल्ट रूप से) SampleStandardDeviation_ForEach()नहीं हो सकते हैं private, इसलिए publicया तो उन्हें या तो अर्जित किया जाना चाहिए था internal, यह मुझे लगता है
फुलप्रूफ

FYI करें: यदि मुझे सही से याद है कि मेरे नमूने में विस्तार विधियाँ उसी वर्ग का हिस्सा थीं जो इस मामले में ==> निजी कार्यों का उपयोग करता था।
सिर्फ एक और मेटाप्रोग्रामर

39

एक तस्वीर एक हजार शब्दों के बराबर होती है

अनुस्मारक:
Func<X, Y, R>प्रकार के दो इनपुट के साथ एक फ़ंक्शन है Xऔर Y, जो टाइप का एक परिणाम देता है R

Enumerable.Aggregate में तीन अधिभार हैं:


अधिभार 1:

A Aggregate<A>(IEnumerable<A> a, Func<A, A, A> f)

Aggregate1

उदाहरण:

new[]{1,2,3,4}.Aggregate((x, y) => x + y);  // 10


यह अधिभार सरल है, लेकिन इसकी निम्नलिखित सीमाएँ हैं:

  • अनुक्रम में कम से कम एक तत्व होना चाहिए,
    अन्यथा फ़ंक्शन एक फेंक देगा InvalidOperationException
  • तत्व और परिणाम एक ही प्रकार के होने चाहिए।



अधिभार 2:

B Aggregate<A, B>(IEnumerable<A> a, B bIn, Func<B, A, B> f)

Aggregate2

उदाहरण:

var hayStack = new[] {"straw", "needle", "straw", "straw", "needle"};
var nNeedles = hayStack.Aggregate(0, (n, e) => e == "needle" ? n+1 : n);  // 2


यह अधिभार सामान्य है:

  • एक बीज मूल्य प्रदान किया जाना चाहिए ( bIn)।
  • संग्रह खाली हो सकता है,
    इस मामले में, फ़ंक्शन परिणाम के रूप में बीज मूल्य प्राप्त करेगा।
  • तत्वों और परिणाम के विभिन्न प्रकार हो सकते हैं।



अधिभार 3:

C Aggregate<A,B,C>(IEnumerable<A> a, B bIn, Func<B,A,B> f, Func<B,C> f2)


तीसरा अधिभार बहुत उपयोगी आईएमओ नहीं है।
वही अधिक अधिभार 2 का उपयोग करके लिखा जा सकता है जिसके बाद एक फ़ंक्शन होता है जो इसके परिणाम को बदल देता है।


चित्र इस उत्कृष्ट ब्लॉगपोस्ट से अनुकूलित किए गए हैं ।


यह एक महान जवाब होगा .... हास्केल के बारे में एक सवाल पर। लेकिन Aggegate.net का कोई अधिभार नहीं है जो एक लेता है Func<T, T, T>
जामीक

4
हाँ है । आप इसे अपने उत्तर में उपयोग करें!
3dGrabber

1
Upvoting क्योंकि आप ध्यान से वर्णन करते हैं कि अनुक्रम खाली होने पर क्या होता है। बता दें कि एन स्रोत में तत्वों की संख्या है। हम मानते हैं कि अधिभार जो ए नहीं लेता है seed, संचायक फ़ंक्शन एन -1 को लागू करता है; जबकि अन्य भार के (कि है ले एक seed) संचायक समारोह लागू एन बार।
जेपी स्टिग नीलसन

17

एग्रीगेट मूल रूप से डेटा या ग्रुप अप करने के लिए उपयोग किया जाता है।

MSDN के अनुसार "अलग-अलग फ़ंक्शन एक अनुक्रम पर एक संचायक फ़ंक्शन को लागू करता है।"

उदाहरण 1: किसी सरणी में सभी संख्याएँ जोड़ें।

int[] numbers = new int[] { 1,2,3,4,5 };
int aggregatedValue = numbers.Aggregate((total, nextValue) => total + nextValue);

* महत्वपूर्ण: डिफ़ॉल्ट रूप से प्रारंभिक कुल मूल्य संग्रह के अनुक्रम में 1 तत्व है। यानी: कुल परिवर्तनीय प्रारंभिक मूल्य डिफ़ॉल्ट रूप से 1 होगा।

चर व्याख्या

कुल: यह फंक द्वारा लौटाए गए मूल्य (कुल मूल्य) का योग रखेगा।

nextValue: यह सरणी अनुक्रम में अगला मान है। यह मान कुल मान यानी कुल में जोड़ा गया है।

उदाहरण 2: एक सरणी में सभी आइटम जोड़ें। 10 से जोड़ने के साथ आरंभिक संचायक मान भी सेट करें।

int[] numbers = new int[] { 1,2,3,4,5 };
int aggregatedValue = numbers.Aggregate(10, (total, nextValue) => total + nextValue);

तर्क स्पष्टीकरण:

पहला तर्क प्रारंभिक (प्रारंभिक मूल्य अर्थात बीज मूल्य) है जिसका उपयोग सरणी में अगले मूल्य के साथ शुरू करने के लिए किया जाएगा।

दूसरा तर्क एक कवक है जो एक कवक है जो 2 इंट लेता है।

1.टोटल: यह गणना के बाद फंक द्वारा लौटाए गए सम मूल्य (कुल मूल्य) से पहले के समान ही होगा।

2.nextValue:: यह सरणी अनुक्रम में अगला मान है। यह मान कुल मान यानी कुल में जोड़ा गया है।

इस कोड को डीबग करना भी आपको एक बेहतर समझ देगा कि कुल मिलाकर कैसे काम करें।


7

जमीक के जवाब से बहुत कुछ सीखा ।

यदि केवल आवश्यकता CSV स्ट्रिंग उत्पन्न करने के लिए है, तो आप यह कोशिश कर सकते हैं।

var csv3 = string.Join(",",chars);

यहां 1 मिलियन स्ट्रिंग्स के साथ एक परीक्षण किया गया है

0.28 seconds = Aggregate w/ String Builder 
0.30 seconds = String.Join 

स्रोत कोड यहाँ है


जब मैंने लिंक में दिए गए कोड के रूप में डॉटनेटफिल्ड.नेट में एक ही कोड चलाया , तो मुझे "स्ट्रिंग" के लिए "घातक त्रुटि: मेमोरी उपयोग की सीमा" पार हो गई। लेकिन एग्रीगेट ने हमेशा अपेक्षा के अनुरूप काम किया। इसलिए मेरा मानना ​​है कि स्ट्रिंग का उपयोग करने की अनुशंसा नहीं की गई है। जोइन
मनीष जैन

अजीब? जब मैंने फर्स्ट स्टॉप वॉच पर टिप्पणी की, जो एग्रीगेट के लिए थी; तब मुझे कोई "घातक त्रुटि नहीं मिल रही है: मेमोरी उपयोग सीमा पार हो गई थी"। कृपया समझाएँ! लिंक: dotnetfiddle.net/6YyumS
मनीष जैन

dotnetfiddle.net की मेमोरी सीमा होती है, जब निष्पादन स्टॉप तक पहुंचता है। यदि आप String.Join कोड से पहले कुल कोड को स्थानांतरित करते हैं, तो आप कुल के लिए त्रुटि प्राप्त कर सकते हैं।
Rm558

7

यहां पहले से ही सभी शानदार उत्तरों के अलावा, मैंने इसका उपयोग परिवर्तन कदमों की एक श्रृंखला के माध्यम से चलने के लिए भी किया है।

यदि एक रूपांतरण को एक के रूप में लागू किया जाता है Func<T,T>, तो आप प्रत्येक चरण के माध्यम से एक उदाहरण को चलने के लिए कई परिवर्तनों को जोड़ सकते हैं List<Func<T,T>>और उपयोग कर सकते हैं ।AggregateT

एक अधिक ठोस उदाहरण

आप एक stringमूल्य लेना चाहते हैं , और इसे पाठ रूपांतरों की एक श्रृंखला के माध्यम से चलते हैं जो प्रोग्रामेटिक रूप से बनाए जा सकते हैं।

var transformationPipeLine = new List<Func<string, string>>();
transformationPipeLine.Add((input) => input.Trim());
transformationPipeLine.Add((input) => input.Substring(1));
transformationPipeLine.Add((input) => input.Substring(0, input.Length - 1));
transformationPipeLine.Add((input) => input.ToUpper());

var text = "    cat   ";
var output = transformationPipeLine.Aggregate(text, (input, transform)=> transform(input));
Console.WriteLine(output);

यह परिवर्तनों की एक श्रृंखला बनाएगा: अग्रणी और अनुगामी रिक्त स्थान निकालें -> पहला वर्ण निकालें -> अंतिम वर्ण निकालें -> ऊपरी-केस में कनवर्ट करें। इस श्रृंखला के चरणों को आवश्यकतानुसार जोड़ा जा सकता है, हटाया जा सकता है या पुन: व्यवस्थित किया जा सकता है, जिससे कि किसी भी प्रकार की परिवर्तन पाइपलाइन की आवश्यकता हो।

इस विशिष्ट पाइपलाइन का अंतिम परिणाम, यह " cat "बन जाता है "A"


यह बहुत शक्तिशाली बन सकता है एक बार जब आप महसूस करते हैं कि कुछ भीT हो सकता है । इसे BitMapउदाहरण के रूप में उपयोग करते हुए, छवि परिवर्तन के लिए उपयोग किया जा सकता है ;


4

परिभाषा

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

इसलिए, एग्रीगेट विधि एक पुनरावर्ती कार्य के सुरक्षित कार्यान्वयन का एक रूप है।

सुरक्षित है , क्योंकि एक संग्रह के प्रत्येक आइटम पर पुनरावृत्ति पुनरावृत्ति होगी और हम गलत निकास स्थिति से किसी भी अनंत लूप निलंबन नहीं प्राप्त कर सकते हैं। पुनरावर्ती , क्योंकि वर्तमान फ़ंक्शन का परिणाम अगले फ़ंक्शन कॉल के लिए एक पैरामीटर के रूप में उपयोग किया जाता है।

वाक्य - विन्यास:

collection.Aggregate(seed, func, resultSelector);
  • बीज - डिफ़ॉल्ट रूप से प्रारंभिक मूल्य;
  • func - हमारे पुनरावर्ती कार्य। यह एक लैम्ब्डा-एक्सप्रेशन, एक फंक प्रतिनिधि या एक फंक्शन टाइप TF (T result, T nextValue) हो सकता है;
  • resultSelector - यह अंतिम परिणाम को बदलने, बदलने, बदलने, बदलने के लिए फंक या अभिव्यक्ति की तरह एक फ़ंक्शन हो सकता है।

यह काम किस प्रकार करता है:

var nums = new[]{1, 2};
var result = nums.Aggregate(1, (result, n) => result + n); //result = (1 + 1) + 2 = 4
var result2 = nums.Aggregate(0, (result, n) => result + n, response => (decimal)response/2.0); //result2 = ((0 + 1) + 2)*1.0/2.0 = 3*1.0/2.0 = 3.0/2.0 = 1.5

व्यावहारिक उपयोग:

  1. संख्या n से गुणनखंड खोजें:

int n = 7;
var numbers = Enumerable.Range(1, n);
var factorial = numbers.Aggregate((result, x) => result * x);

जो इस कार्य के समान कार्य कर रहा है:

public static int Factorial(int n)
{
   if (n < 1) return 1;

   return n * Factorial(n - 1);
}
  1. एग्रीगेट () सबसे शक्तिशाली LINQ एक्सटेंशन मेथड में से एक है, जैसे Select () और कहां ()। हम इसका उपयोग सम (), मिन () को बदलने के लिए कर सकते हैं। अधिकतम (), औसत () कार्यक्षमता, या अतिरिक्त संदर्भ लागू करके इसे बदलने के लिए:
    var numbers = new[]{3, 2, 6, 4, 9, 5, 7};
    var avg = numbers.Aggregate(0.0, (result, x) => result + x, response => (double)response/(double)numbers.Count());
    var min = numbers.Aggregate((result, x) => (result < x)? result: x);
  1. विस्तार विधियों का अधिक जटिल उपयोग:
    var path = @“c:\path-to-folder”;

    string[] txtFiles = Directory.GetFiles(path).Where(f => f.EndsWith(“.txt”)).ToArray<string>();
    var output = txtFiles.Select(f => File.ReadAllText(f, Encoding.Default)).Aggregate<string>((result, content) => result + content);

    File.WriteAllText(path + summary.txt”, output, Encoding.Default);

    Console.WriteLine(“Text files merged into: {0}”, output); //or other log info

बहुत अच्छा पहला जवाब। बहुत बढ़िया! शर्म की बात है कि यह इतना पुराना सवाल है या आपको बहुत सारे
अपवोट मिले होंगे

1

यह Aggregateएक धाराप्रवाह एपीआई जैसे कि लाइनक सॉर्टिंग पर उपयोग करने के बारे में एक स्पष्टीकरण है ।

var list = new List<Student>();
var sorted = list
    .OrderBy(s => s.LastName)
    .ThenBy(s => s.FirstName)
    .ThenBy(s => s.Age)
    .ThenBy(s => s.Grading)
    .ThenBy(s => s.TotalCourses);

और देखते हैं कि हम एक प्रकार का फ़ंक्शन लागू करना चाहते हैं जो फ़ील्ड का एक सेट लेते हैं, Aggregateफॉर-लूप के बजाय यह बहुत आसान है , जैसे:

public static IOrderedEnumerable<Student> MySort(
    this List<Student> list,
    params Func<Student, object>[] fields)
{
    var firstField = fields.First();
    var otherFields = fields.Skip(1);

    var init = list.OrderBy(firstField);
    return otherFields.Skip(1).Aggregate(init, (resultList, current) => resultList.ThenBy(current));
}

और हम इसे इस तरह से उपयोग कर सकते हैं:

var sorted = list.MySort(
    s => s.LastName,
    s => s.FirstName,
    s => s.Age,
    s => s.Grading,
    s => s.TotalCourses);

1

सभी ने अपना स्पष्टीकरण दिया है। मेरी व्याख्या ऐसी ही है।

एकत्रीकरण विधि एक संग्रह के प्रत्येक आइटम के लिए एक फ़ंक्शन लागू करती है। उदाहरण के लिए, हमारे पास संग्रह {6, 2, 8, 3} और फ़ंक्शन जोड़ें (ऑपरेटर +) यह करता है ((6 + 2) +8) +3) और 19 लौटाता है

var numbers = new List<int> { 6, 2, 8, 3 };
int sum = numbers.Aggregate(func: (result, item) => result + item);
// sum: (((6+2)+8)+3) = 19

इस उदाहरण में लैम्बडा एक्सप्रेशन के बजाय विधि नाम दिया गया है।

var numbers = new List<int> { 6, 2, 8, 3 };
int sum = numbers.Aggregate(func: Add);
// sum: (((6+2)+8)+3) = 19

private static int Add(int x, int y) { return x + y; }

0

एक छोटी और आवश्यक परिभाषा यह हो सकती है: लिन्क एग्रीगेट एक्सटेंशन विधि किसी सूची के तत्वों पर लागू किए गए एक प्रकार के पुनरावर्ती कार्य को घोषित करने की अनुमति देती है, जिनमें से ऑपरेंड दो होते हैं: वे तत्व जिनमें वे सूची में मौजूद हैं; एक समय में एक तत्व, और पिछले पुनरावर्ती पुनरावृत्ति का परिणाम या कुछ भी नहीं यदि अभी तक पुनरावृत्ति नहीं हुई है।

इस तरह आप संख्याओं के फैक्टरियल या संगीन तारों की गणना कर सकते हैं।


0

एक बहु आयामी पूर्णांक सरणी में स्तंभों को योग करने के लिए प्रयोग किया जाता है

        int[][] nonMagicSquare =
        {
            new int[] {  3,  1,  7,  8 },
            new int[] {  2,  4, 16,  5 },
            new int[] { 11,  6, 12, 15 },
            new int[] {  9, 13, 10, 14 }
        };

        IEnumerable<int> rowSums = nonMagicSquare
            .Select(row => row.Sum());
        IEnumerable<int> colSums = nonMagicSquare
            .Aggregate(
                (priorSums, currentRow) =>
                    priorSums.Select((priorSum, index) => priorSum + currentRow[index]).ToArray()
                );

अनुक्रमणिका के साथ चयन का उपयोग एग्रीगेट फंक के भीतर मिलान स्तंभों को जोड़ने और एक नया ऐरे वापस करने के लिए किया जाता है; {३ + २ = ५, १ + ४ = ५, = + १६ = २३, = + ५ = १३}।

        Console.WriteLine("rowSums: " + string.Join(", ", rowSums)); // rowSums: 19, 27, 44, 46
        Console.WriteLine("colSums: " + string.Join(", ", colSums)); // colSums: 25, 24, 45, 42

लेकिन बूलियन सरणी में ट्रूज़ की संख्या की गिनती करना अधिक कठिन है क्योंकि संचित प्रकार (इंट) स्रोत प्रकार (बूल) से भिन्न होता है; दूसरे अधिभार का उपयोग करने के लिए यहां एक बीज आवश्यक है।

        bool[][] booleanTable =
        {
            new bool[] { true, true, true, false },
            new bool[] { false, false, false, true },
            new bool[] { true, false, false, true },
            new bool[] { true, true, false, false }
        };

        IEnumerable<int> rowCounts = booleanTable
            .Select(row => row.Select(value => value ? 1 : 0).Sum());
        IEnumerable<int> seed = new int[booleanTable.First().Length];
        IEnumerable<int> colCounts = booleanTable
            .Aggregate(seed,
                (priorSums, currentRow) =>
                    priorSums.Select((priorSum, index) => priorSum + (currentRow[index] ? 1 : 0)).ToArray()
                );

        Console.WriteLine("rowCounts: " + string.Join(", ", rowCounts)); // rowCounts: 3, 1, 2, 2
        Console.WriteLine("colCounts: " + string.Join(", ", colCounts)); // colCounts: 3, 2, 1, 2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.