C # वस्तुओं की सूची, मुझे एक संपत्ति का योग कैसे मिलेगा


158

मेरे पास वस्तुओं की एक सूची है। व्यक्तिगत वस्तु प्रविष्टि की एक संपत्ति राशि है। मुझे राशि का योग कैसे मिलेगा?

यदि मेरी सूची डबल टाइप की होती तो मैं ऐसा कुछ कर पाता:

double total = myList.Sum();

हालाँकि मैं इसके समान कुछ करना चाहता हूं, फिर भी यह वाक्य रचना गलत है।

double total = myList.amount.Sum();

मुझे इसे पूरा करने के बारे में कैसे जाना चाहिए? यदि संभव हो तो मूल्य की गणना और गणना के बजाय मैं सम फ़ंक्शन का उपयोग करना पसंद करूंगा।

जवाबों:


310
using System.Linq;

...

double total = myList.Sum(item => item.Amount);

12
क्या यह ब्याज से बाहर निकलने की तुलना में तेज है?
Coops

4
मुझे @ CodeBlend के सवाल में भी दिलचस्पी है। क्या यह गणना लूप के लिए तेजी से होगी?
रेक्स

23
@Coops - आपके प्रश्न का उत्तर देने के लिए ... 100,000 ऑब्जेक्ट्स वाली एक सूची का उपयोग करके, प्रत्येक ऑब्जेक्ट में डेटाटाइप डबल की एकल संपत्ति होती है, ऊपर के समाधान (myList.Sum) का उपयोग करके संपत्ति को 1,000 गुना करने के लिए 0.44 सेकंड की तुलना में 2.44 सेकंड का समय लगता है। । बीता हुआ समय सटीकता के लिए स्टॉपवॉच वर्ग का उपयोग करके मापा जाता है। इसलिए myList.Sum का उपयोग करने की तुलना में foreach 2x से अधिक तेज़ है।
बजे जो गेयटी

36

और यदि आप इसे उन वस्तुओं पर करना चाहते हैं जो एक विशिष्ट स्थिति से मेल खाते हैं ...

double total = myList.Where(item => item.Name == "Eggs").Sum(item => item.Amount);

11

एक अन्य विकल्प:

myPlanetsList.Select(i => i.Moons).Sum();

5
इसके बजाय .Select(i => i.Moons).Sum()आप उपयोग कर सकते हैं.Sum(i => i.Moons)
मेसन

1
@ मेसन, सही है और इस तरह एलेक्स ने अपने पहले के उत्तर में समस्या का सामना किया, इसलिए मैंने बस एक ही काम करने का एक अलग तरीका प्रदान किया।
उपयोगी

1
आह हाँ, मेरी ग़लतफ़हमी के लिए खेद है।
मेसोन

मैं सराहना करता हूं कि यह एक अनोखा जवाब है, लेकिन प्रदर्शन में दिक्कत नहीं आएगी?
पीटर लेनजो

2

यहाँ उदाहरण कोड है जिसे आप इस तरह के परीक्षण के लिए चला सकते हैं:

var f = 10000000;
var p = new int[f];

for(int i = 0; i < f; ++i)
{
    p[i] = i % 2;
}

var time = DateTime.Now;
p.Sum();
Console.WriteLine(DateTime.Now - time);

int x = 0;
time = DateTime.Now;
foreach(var item in p){
   x += item;
}
Console.WriteLine(DateTime.Now - time);

x = 0;
time = DateTime.Now;
for(int i = 0, j = f; i < j; ++i){
   x += p[i];
}
Console.WriteLine(DateTime.Now - time);

जटिल वस्तु के लिए एक ही उदाहरण है:

void Main()
{
    var f = 10000000;
    var p = new Test[f];

    for(int i = 0; i < f; ++i)
    {
        p[i] = new Test();
        p[i].Property = i % 2;
    }

    var time = DateTime.Now;
    p.Sum(k => k.Property);
    Console.WriteLine(DateTime.Now - time);

    int x = 0;
    time = DateTime.Now;
    foreach(var item in p){
        x += item.Property;
    }
    Console.WriteLine(DateTime.Now - time);

    x = 0;
    time = DateTime.Now;
    for(int i = 0, j = f; i < j; ++i){
        x += p[i].Property;
    }
    Console.WriteLine(DateTime.Now - time);
}

class Test
{
    public int Property { get; set; }
}

संकलक अनुकूलन के साथ मेरे परिणाम हैं:

00:00:00.0570370 : Sum()
00:00:00.0250180 : Foreach()
00:00:00.0430272 : For(...)

और दूसरे परीक्षण के लिए हैं:

00:00:00.1450955 : Sum()
00:00:00.0650430 : Foreach()
00:00:00.0690510 : For()

ऐसा लगता है कि LINQ आमतौर पर foreach (...) की तुलना में धीमा है, लेकिन मेरे लिए जो अजीब है वह यह है कि foreach (...) लूप की तुलना में अधिक तेज़ प्रतीत होता है।


2
भविष्य में संदर्भ के लिए, पर एक नजर है Stopwatchमें System.Diagnosticsके रूप में यह एक उच्च प्रदर्शन समय रिकॉर्डर है। (मैं आप btw नीचे नहीं था)
Meirion ह्यूजेस

1
DateTime.Nowमापने के लिए उपयोग न करें । इसका भयानक प्रदर्शन है क्योंकि यह हमेशा स्थानीय समय पर लौटता है। DateTime.UtcNowज्यादा तेज़ है; हालाँकि, यह अभी भी Stopwatchकक्षा के रूप में उच्च रिज़ॉल्यूशन का उपयोग नहीं करता है ।
ग्योर्गी कोसजेग

3
इस सवाल का जवाब नहीं है।
मार्क पैटिसन

ठीक है, टिप के लिए धन्यवाद। स्कोर बहुत दोहराने योग्य हैं, इसलिए मैंने यह मान लिया कि इस तरह का संकल्प पर्याप्त है
Puchacz

2
जबकि आपका इरादा अच्छा है -मार्क सही है- आप स्पष्ट रूप से सवाल का जवाब नहीं दे रहे हैं। मैं आपको इसे बदलने की सलाह दूंगा: "यहां बताया गया है कि आप इसे कैसे कर सकते हैं" और "यहां प्रत्येक विकल्प का सीपीयू प्रदर्शन है"। सिद्धांत रूप में भी यदि आप अपनी परीक्षण पद्धति का वर्णन करते हैं, तो आपको हमें कोड नहीं दिखाना होगा।
मीरियन ह्यूजेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.