2012-01-04 7 views
20

तो मैं ऐसा दिखता है स्ट्रिंग की एक सूची है:Linq: कैसे दूसरे को पाने के लिए पिछले

var ls=new List<string>() 
    { 
     "100", 
     "101-102-1002", 
     "105-153-1532-1532", 
     "105-1854-45-198", 
     "180-95-45-200" 
    }; 

मैं विभाजन स्ट्रिंग के दूसरे पिछले प्राप्त करना चाहते हैं। तो मेरी उत्पादन इस तरह दिखता है:

ls.Select (l =>l.Split('-').Select ((s,i) =>new {s,i}) 
.OrderByDescending (x=>x.i).Skip(1).Take(1)) 

मुझे लगता है कि इस समाधान इस सरल कार्य के लिए जटिल हो सकता है:

null, 
102, 
1532, 
45, 
45 

मैं इसके लिए एक समाधान है कि इस तरह दिखता है। तो मेरा सवाल है: क्या आप में से किसी को भी इस समस्या का आसान समाधान है?

+2

पावेल Gatilov के उत्तर के आधार पर परिणाम गलत है या मैं सवाल नहीं मिलता बना लिया है: ऐसा नहीं होना चाहिए हो: शून्य, 102,153,1235? –

+1

आपका समाधान मुझे ठीक लग रहा है! – ColinE

+0

हां यह स्प्लिट स्ट्रिंग का दूसरा अंतिम होना चाहिए। यदि कोई दूसरा अंतिम नहीं है तो इसे शून्य वापस करना चाहिए। – Arion

उत्तर

31

Reverse अच्छी तरह से यहाँ फिट बैठता है:

ls.SelectMany(l =>l.Split('-').Reverse().Skip(1).Take(1).DefaultIfEmpty()) 

मैं भी SelectMany का उपयोग <IEnumerable<string> को IEnumerable<IEnumerable<string>> को बदलने के लिए।

+1

इस समाधान के साथ एकमात्र समस्या यह है कि आपको 'शून्य' नहीं मिलेगा जब विभाजित सरणी लंबाई 2 से कम है। यह करीब है लेकिन यह सही नहीं है क्योंकि यह 'शून्य' ls के बजाय खाली हो जाता है। चयन करें (x => x ।। .Split ('-') रिवर्स() पर जाएं (1) .Take (1) .FirstOrDefault()) ToList();। – Anand

+0

@ अंदंद हाँ, संकेत के लिए धन्यवाद। हालांकि, मैं LINQ monad में रहने के लिए अपने LINQ कोड को प्राथमिकता देता हूं। –

+0

@TimSchmelter मैं आपको नहीं मिला। यदि 'ls' खाली है, तो परिणाम खाली हो जाएगा। यदि 'ls' में कोई आइटम बहुत छोटा है और इसमें कम से कम 2 घटक नहीं हैं, तो परिणाम उस आइटम के स्थान पर 'शून्य' होगा। यह व्यवहार हालांकि अजीब लग सकता है, लेकिन लेखक यही चाहता है, है ना? –

2
var ls = new List<string> { "100", "101-102-1002", "105-153-1532-1532", "12-1235-785" }; 
var result = ls.Select(x => 
{ 
    var tokens = x.Split('-'); 
    if (tokens.Length < 2) 
    { 
     return null; 
    } 
    return tokens[tokens.Length - 2]; 
}); 
12
 var ls = new List<string>() { "100", "101-102-1002", "105-153-1532-1532", "12-1235-785" }; 
     var result = from p in ls 
        let arr = p.Split('-') 
        select arr.Length < 2 ? null : arr[arr.Length - 2]; 

     foreach (var item in result) 
     { 
      Console.WriteLine(item); 
     } 



     Console.Read(); 
+0

यह जवाब होना चाहिए था। यह दूसरे की तुलना में तेज़ है। – DanielCuadra

6
var ls = new List<string>(){"100","101-102-1002","105-153-1532-1532","12-1235-785"}; 

var result = from l in ls 
      let s = l.Split('-') 
      select s.ElementAtOrDefault(s.Length - 2); 
+0

लंबाई कम होने पर 'शून्य' नहीं थकाता है इसके बजाय FirstOrDefault खाली हो जाता है। – Anand

+0

@ एंड, सुनिश्चित नहीं है कि आपका क्या मतलब है, यह पहली प्रविष्टि के लिए 'शून्य' वापस करता है। –

6

आप

var ls = new List<string>(...);

है तो

var result = ls.Reverse().Skip(1).Take(1);

काम करना चाहिए।

0

लैम्ब्डा वाक्य रचना में:

var ls = new List<string>() { "100", "101-102-1002", "105-153-1532-1532", "12-1235-785" }; 

var result = ls.Select(x => new { split = x.Split('-') }).Select(y => y.split.LastOrDefault(z => z != y.split.LastOrDefault())); 
+0

तो आप जानते हैं, अगर आप अपना टेक्स्ट हाइलाइट करते हैं और "कोड" बटन दबाते हैं तो यह आपके लिए कोड ब्लॉक के रूप में प्रदर्शित करने के लिए सही ढंग से प्रारूपित करेगा। मैं आगे बढ़ गया हूं और इस बार सबमिट और संपादित कर रहा हूं। – Amicable

1

मैं एक विस्तार ऊपर

public static TSource SecondLast<TSource>(this IEnumerable<TSource> source) 
{ 
      //from http://stackoverflow.com/questions/8724179/linq-how-to-get-second-last 
      return source.Reverse().Skip(1).Take(1).FirstOrDefault(); 
} 
संबंधित मुद्दे