2012-09-06 46 views
2

我有一個字符串變量,其中包含[l=9;f=0;r=5;p=2]。可能有多個:[l=9;f=0;r=5;p=2],[l=9;f=0;r=6;p=2]來自字符串的子串值

我想獲得ListTuple<int,int,int>,其中item1 = value of l, item2= value of r, item3=value of p。什麼是最好的方法來做到這一點?
我的代碼:

// split string 
    var splittedFormatedSeats = Regex.Matches(formatSeats, @"\[.+?\]") 
          .Cast<Match>() 
          .Select(m => m.Value) 
          .ToList(); 


    IList<Tuple<int,int,int>> fullSeat = new List<Tuple<int, int, int>>(); 
     foreach (var splittedFormatedSeat in splittedFormatedSeats) 
     { 

      ... 
     } 

感謝。

+0

'f'變量會發生什麼? – KyorCode

+0

@KyorCode:沒什麼,只是跳過它。 – user1260827

+2

「最佳方法」是什麼?可讀性?性能?最大限度地使用LINQ?最少量的代碼?還有別的嗎? – Oded

回答

3

我會採取另一種策略。首先,你的字符串分割子

var components = formatSeats.Split(','); 

這會給你的字符串數組。這將更有效地解析小塊字符串而不是大字符串。

然後,可以使用一個Regex以提取值或一個簡單的這樣的代碼:

foreach(var component in components) 
{ 
    var parts = component.Trim("[]".ToCharArray()).Split(';'); 

} 

var results = from component in components 
       let c = component.Trim("[]".ToCharArray()) 
           .Split(';') 
           .Select(c=>int.Parse(c.SubString(2)) 
       select new { l = c[0], f=c[1], r=c[2], p = c[3] }; 

這將產生一個匿名類型的枚舉。

foreach(var x in results) 
{ 
    Console.WriteLine("{0}/{1}/{2}/{3}", x.l, x.f, x.r, x.p); 
} 

如果你確實需要一個Tuple簡單地改變代碼:

var results = from component in components 
       let c = component.Trim("[]".ToCharArray()) 
           .Split(';') 
           .Select(c=>int.Parse(c.SubString(2)) 
       select new Tuple<int,int,int,int>{ l = c[0], f=c[1], r=c[2], p = c[3] }; 

我會然而,提倡寫一個小結構來簡化代碼,提高可讀性。

public struct MyValue 
{ 
    private readonly int m_L; 
    public int L { get {return m_L; } } 

    private readonly int m_F; 
    public int F { get {return m_F; } } 

    private readonly int m_R; 
    public int R { get {return m_R; } } 

    private readonly int m_P; 
    public int P { get {return m_P; } } 

    public MyValue(int l, int f, int r, int p) 
    { 
     m_L = l; 
     m_F = f; 
     m_R = r; 
     m_P = p; 
    } 
} 
.... 


var results = from component in components 
      let c = component.Trim("[]".ToCharArray()) 
           .Split(';') 
           .Select(c=>int.Parse(c.SubString(2)) 
      select new MyValue(c[0],c[1],c[2],c[3]); 

最後,如果字符串總是有這種形式,你可以避免使用正則表達式。

1

您的內部字符串的格式是否始終相同? 它是否總是每個變量的單個數字值(l,f,r & p)?

如果是這樣,你可以將它們串起來。

foreach(var splittedFormatedSeat in splittedFormatedSeats) 
{ 
    int x, y, z; 
    string s = splittedFormatedSeat .ToString(); 
    if(int.TryParse(s[3].ToString(), out x) && 
     int.TryParse(s[11].ToString(), out y) && 
     int.TryParse(s[15].ToString(), out z)) 
     fullSeat.Add(new Tuple<int,int,int>(x,y,z)); 
} 
2
 string formattedString = "[l=9;f=0;r=5;p=2],[l=9;f=0;r=6;p=2]"; 
     var splitString = formattedString.Split(',') 
            .Select(p => p.Trim(new char[]{'[',']',' '})); 

     List<Tuple<int, int, int, int>> tupleList = new List<Tuple<int, int, int, int>>(); 
     foreach (var item in splitString) 
     { 
      int[] finalSplit = item.Split(';').Select(p => 
                 Convert.ToInt32(p.Substring(p.LastIndexOf('=')+1).Trim()) 
                ).ToArray(); 
      tupleList.Add(new Tuple<int, int, int, int>(finalSplit[0], finalSplit[1], 
            finalSplit[2], finalSplit[3])); 
     } 

這將分裂L,F,R 1和p的值,並且將它們添加到元組。

相關問題