2012-11-23 17 views
6

"41,42x, 43" gibi bir dize listesini dönüştürmek için daha iyi bir yol bulabilirim (belki de güzel bir linq ifadesiyle) geçerli uzunların listesi. Aşağıdaki kod çalışır, ancak sadece çirkin hisseder.Bir dize listesini geçerli listeye dönüştürmek için temiz bir yöntem mi arıyorsunuz? <long> C#

string addressBookEntryIds = "41,42x,43"; 
var ids = addressBookEntryIds.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries); 
var addressBookEntryIdList =new List<long>(); 
foreach (var rec in ids) 
{ 
    long val; 
    if (Int64.TryParse(rec, out val)) 
    { 
     addressBookEntryIdList.Add(val); 
    } 
} 

cevap

4
string addressBookEntryIds = "41,42x,43"; 

Func<string, long?> safeParse = (s) => { 
      long val; 
      if (Int64.TryParse(s, out val)) 
      { 
       return val; 
      } 
      return null;  
}; 


var longs = (from s in addressBookEntryIds.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) 
      let cand = safeParse(s) 
      where cand.HasValue 
      select cand.Value).ToList(); 
+0

Bunu Linqpad'de test ettim; Kodumda güvensiz girdiyle benzer bir şey yapıyorum, ancak kaynak verilerim SQL'den geliyor. Bunun hiçbir şekilde daha güzel olduğunu söylemeyeceğim - orijinal kodunuzun iyi olduğunu düşünüyorum. Bu özlü, açık ve noktaya. – SAJ14SAJ

3

kullanım regex

var list = Regex.Matches(@"41,42x,43", @"\d+").Cast<Match>().Select(x => Convert.ToInt64(x.Value)).ToList(); 
+0

. 42x43, referans uygulamaya dayanması gerektiği gibi sıfır olmayan iki giriş oluşturur. – SAJ14SAJ

0

oldukça gereksiz kodunuzun Sadece bir türetme, (TryParse kullanır ve sonra tekrar Ayrıştırma), ama çalıştığını düşünüyorum:

addressBookEntryIds.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries) 
        .Where(id => 
        { 
         long val; 
         return Int64.TryParse(id, out val); 
        }) 
        .Select(id => Int64.Parse(id)); 
+0

Herkese girişleri için teşekkürler. Her şey yardımcı olur. –

1

Peki, burada bir LINQ sürümü, ama gerçekten daha az çirkin değil!

string addressBookEntryIds = "41,42x,43"; 
var ids = addressBookEntryIds.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); 

Int64 converted; // Working value used within the select 
IEnumerable<Int64> values = ids.Select(x => new 
{ 
    Success = Int64.TryParse(x, out converted), 
    Value = converted 
}).Where(x => x.Success) 
    .Select(x => x.Value); 

bu çözüm ve Anderson en arasındaki fark TryParse sadece girdinin başına bir kez denir olmasıdır.

1

Burada başka LINQ sürümü: Bir sorgu ifadesini tercih ederseniz

String addressBookEntryIds = "41,42x,43"; 
Int64 val = 0; 

addressBookEntryIds 
    .Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) 
    .Where(id => Int64.TryParse(id, out val)) 
    .Select(id => val) 
    .ToList() 

, şunları kullanabilirsiniz:

veya formdaki girdileri bağlı çalışmıyor olabilir
from id in addressBookEntryIds.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) 
where Int64.TryParse(id, out val) 
select val 
İlgili konular