2012-11-23 29 views
6

我希望找到一個更好的方法(也許有一個很好的linq表達式)將字符串列表像「41,42x,43」轉換爲有效期的列表。下面的代碼有效,但感覺很難看。尋找一個乾淨的方式來將字符串列表轉換爲有效列表<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); 
    } 
} 

回答

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

我在Linqpad中測試了這個;我在代碼中執行類似於不安全輸入的操作,但我的源數據實際上來自SQL。我不會說這在任何方面都更漂亮 - 我認爲你的原始代碼很好。它簡潔明瞭,重點突出。 – SAJ14SAJ

3

使用正則表達式

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

,可能會或可能不會取決於形式項工作。 42x43會創建兩個條目,而不是零,因爲它應該基於參考實現。 – SAJ14SAJ

0

你的代碼只是一個推導,相當的冗餘(使用的TryParse,然後再解析),但我認爲它的工作原理:

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

感謝大家的意見。這一切都有幫助。 –

1

那麼,這裏的一個LINQ版本,但它並不是那麼難看!

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); 

這個解決方案和安德森之間的區別是,TryParse只調用每個條目一次。

1

下面是另一個LINQ版本:

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

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

如果你喜歡一個查詢表達式,你可以使用:

from id in addressBookEntryIds.Split(new[] {',', ';'}, StringSplitOptions.RemoveEmptyEntries) 
where Int64.TryParse(id, out val) 
select val