2009-03-24 10 views
5

मैं ऐसा कुछ क्यों कर सकता हूं?एक foreach के साथ सशर्त लैम्ब्डा कथन का उपयोग एक सूची पर कार्रवाई

अगर मैं आइटम के साथ एक List<String> myList आबादी है, मैं तो जैसे एक सशर्त रास्ते में प्रत्येक सदस्य पर कार्य करने के लिए सक्षम होना चाहते हैं:

myList.ForEach(a => { if (a.Trim().Length == 0) a = "0.0"; }) 

लेकिन इस संकलन नहीं होंगे। मैं वापसी मूल्य खोने के साथ कुछ करने का अनुमान लगा रहा हूँ?

मैं युगल में रूपांतरण के लिए तारों की एक सूची तैयार करने की कोशिश कर रहा हूं, और मैं खाली वस्तुओं को '0.0' दिखाने के लिए चाहता हूं ताकि मैं पूरी सूची को एक ही बार में परिवर्तित कर सकूं।

+1

मैं अत्यधिक तुम यात्रा करने के लिए www.lambdaexpression.net – Delashmate

उत्तर

6

फॉरएच म्यूटेबल नहीं है, यह डेटा संरचना को किसी भी तरह से नहीं बदलता है।

आप या तो:

  1. पाश अपने आप को संभाल, एक सूचकांक
  2. एक नई सूची निर्माण, का उपयोग कर .Select और .ToList
(आप .NET 3.5 का उपयोग कर रहे प्रदान की) के साथ

# 1 का उदाहरण:

for (Int32 index = 0; index < myList.Count; index++) 
    if (myList[index].Trim().Length == 0) 
     myList[index] = "0.0"; 
.NET 3.5 और LINQ के साथ

:

myList = (from a in myList 
      select (a.Trim().Length == 0) ? "0.0" : a).ToList(); 
.NET 3.5, Linq-सिंटैक्स का उपयोग नहीं है, लेकिन Linq-कोड का उपयोग कर के साथ

:

myList = myList.Select(a => (a.Trim().Length == 0) ? "0.0" : a).ToList(); 

संपादित: आप युगल की एक नई सूची का उत्पादन करना चाहते हैं, तुम भी है कि एक ही बार में LINQ का उपयोग कर सकते हैं:

List<Double> myDoubleList = 
    (from a in myList 
    select (a.Trim().Length == 0 ? "0" : a) into d 
    select Double.Parse(d)).ToList(); 

ध्यान दें कि बजाय सिर्फ "0" दशमलव बिंदु पर निर्भर करता है किया जा रहा है पूर्ण विराम सी का उपयोग करते हुए "0.0" haracter। अपने सिस्टम पर ऐसा नहीं है, तो मैं सिर्फ़ वही "0" बदल दिया, लेकिन एक और अधिक उचित तरीके से एक स्पष्ट सांख्यिक स्वरूपण लेने के लिए Double.Parse करने के लिए कॉल को बदलने के लिए, इस तरह होगा:

List<Double> myDoubleList = 
    (from a in myList 
    select (a.Trim().Length == 0 ? "0.0" : a) into d 
    select Double.Parse(d, CultureInfo.InvariantCulture)).ToList(); 
+0

हममम ठीक है, वहाँ किसी भी विस्तार विधि है कि आप सूची में प्रत्येक आइटम पर कार्रवाई करने की अनुमति देगा है की सलाह देते हैं? – Alex

+0

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

+0

धन्यवाद। नामकरण के लिए – Alex

4

क्या आप संभवतः चाहते हैं:

public static void MutateEach(this IList<T> list, Func<T, T> mutator) 
{ 
    int count = list.Count; 
    for (int n = 0; n < count; n++) 
     list[n] = mutator(list[n]); 
} 

कौन सा अनुमति होगी:

myList.MutateEach(a => (a.Trim().Length == 0) ? "0.0" : a); 

बस अपने खुद की एक सार्वजनिक स्थैतिक कक्षा में MutateEach विधि डाल दिया और सुनिश्चित करें कि आप एक निर्देश का उपयोग किया है कि इसे मिल जाएगा

चाहे ऐसा कुछ परिभाषित करने लायक है, इस पर निर्भर करता है कि आप इसका कितनी बार उपयोग करेंगे। ध्यान दें कि इसे IEnumerable के बजाय IList पर विस्तार होना है, इसलिए हम अपडेट कर सकते हैं, जो इसे कम व्यापक रूप से लागू करता है।

+0

+1, जो इसे एक अच्छा एक्सटेंशन बना देगा। –

+1

आप लोग शानदार हैं। हर बार जब मैं इस साइट पर एक प्रश्न पूछता हूं तो मैं कुछ सीखता हूं। – Alex

0

@ डैनियल-कानविकर MutateEach एक्सटेंशन समाधान एक अच्छा समाधान है।


हालांकि, एक नया List लौटने के लिए, आप List.ConvertAll<TTo>(Converter<TFrom,TTo>(Func<TFrom, TTo>)) है, जो चारों ओर .NET 2.0 के बाद से किया गया है का उपयोग करने का विकल्प है।

यह Linq, या लैम्ब्डानहीं है।

List<String> nodeStringList = new List<String>(new String[] { "", "0.5 ", " 1.1"}); 

nodeStringList = nodeStringList.ConvertAll<String>((c) => (c.Value.Trim().Length != 0) ? c.Value.Trim() : "0.0"); 

MSDN Reference - List.ConvertAll

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