2010-09-29 149 views
10

我想避免循環分割字符串列出<string>使用LINQ

我有這樣的:

string s = "AAAA,12,BBBB,34,CCCCC,56"; 

使用LINQ,我想有2列表

在第一種: AAAA,BBBB和CCCCC

在第二:12,34和56

它不是基於NUM eric或不是數字。

感謝,

+1

什麼是基於字符串的劃分?在列表中的位置,字符數量等? – 2010-09-29 12:10:39

+0

是的,它在列表中的位置 – 2010-09-29 12:12:36

+2

'我想要避免循環'你確實意識到,無論你決定的LINQ解決方案實際上是否會使用至少一個循環? – 2010-09-29 12:29:02

回答

29

您可以使用

var str = "AAAA,12,BBBB,34,CCCCC,56"; 

var spl = str.Split(','); 
var l1 = spl.Where((x, y) => y % 2 == 0).ToList(); 
var l2 = spl.Where((x, y) => y % 2 == 1).ToList(); 

這是要檢查,如果該指數爲偶數或奇數。

1
+0

儘管這個鏈接可能回答這個問題,但最好在這裏包含答案的重要部分,並提供供參考的鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 - [來自評論](/ review/low-quality-posts/18997612) – 2018-03-04 03:22:01

6

鑑於該規則是,你要在一個列表中的每個第二個字符串,而在另一個列表中的其他人,你可以做這樣的事情:

 string s = "AAAA,12,BBBB,34,CCCCC,56"; 

     var parts = s.Split(','); 

     var first = parts.Where((p, i) => i % 2 == 0); 
     var second = parts.Where((p, i) => i % 2 == 1); 
2

我不知道你的最終目標是什麼,但你可以試試這個:

var strings = s.Split(',').Where((s,p) => p % 2 == 0) 
-1

如果列表中沒有與每一個第二有序是一個數字,你可以做事端這樣

var stringList = "AAAA,12,BBBB,34,CCCCC,56".Split(','); 

var intsAsStrings = stringList.Where(
     (x) => 
     { 
      int i; 
      return int.TryParse(x, out i); 
     }).ToList(); 

var strings = stringList.Where(x => !intsAsStrings.Contains(x)).ToList(); 
+0

爲什麼不簡單地使用Except而不是Where(x =>!intsAsStrings.Contains(x))?這也不是這個問題的作者想要的。 – sloth 2010-09-29 12:26:15

+0

不知道Except方法,不錯。 – Xorandor 2010-09-29 12:36:58

1

這裏g是對於那些有興趣的ISNUMERIC,而不是數字濾波器...我意識到它並不需要

string x = "AAAA,12,BBBB,34,CCCCC,56"; 

Regex _isNumber = new Regex(@"^\d+$"); 

string[] y = x.Split(',') .Where(a => _isNumber.IsMatch(a)).ToArray(); 
string[] z =x.Split(',') .Where(a => !_isNumber.IsMatch(a)).ToArray(); 
8

允許使用Aggregate爲它的樂趣(和也,證明這可以作爲一個單一的表達來完成):

"AAAA,12,BBBB,34,CCCC,56".Split(',').Aggregate(
    new { Uneven = new List<string>(), Even = new List<string>() }, 
    (seed, s) => { 
     if (seed.Uneven.Count > seed.Even.Count) 
      seed.Even.Add(s); 
     else 
      seed.Uneven.Add(s); 
     return seed; 
    }); 

根據LINQPad,結果是這樣的: alt text

當然,我可能不會這樣做,因爲它很難閱讀。並且,要追加到哪個列表的測試是,不好看。

但至少我們現在有另一個lambda語句的示例 - 通常LINQ文獻試圖忘記它們(可能是因爲它們不適用於SQL或任何其他使用表達式樹的後端)。

與上述更清潔的解決方案相反,此方法的一個優點是這隻能使一個通過列表。因爲我們正在分割一個字符串,所以我會嘗試在其他地方進行優化;)IEnumerable<string> Split(this string self, string boundary)會不會很酷?

+0

呃,很酷。幾乎沒有現實世界但很酷。 – 2010-09-29 12:52:07

+0

不知何故,如果累加器函數修改了源參數,它看起來像是一個奇怪的「Aggregate」濫用。感覺就像遵循函數式編程的邏輯,同時又違背了精神。我是唯一一個這樣認爲的人嗎? – Niki 2010-09-29 12:56:11

+0

@nikie與「源參數」你的意思是'TSource'(未修改)或'TAccumulate'(已修改,但並非總是如此?) – 2010-09-29 13:12:02

1

您可以在位置和extrat您從組列表,像這樣組:

 public IEnumerable<IEnumerable<T>> ToLists<T>(IEnumerable<T> sequence) 
     { 
      var res = sequence.Select((item, position) => new { Item = item, Position = position }) 
           .GroupBy(pair => pair.Position % 2 == 0,pair => pair.Item); 
      return from grouping in res 
        select grouping; 
     } 

如果您需要的名單是兩種不同類型,你可以遍歷結果的。 這就是爲什麼返回類型不是IEnumerable> IEnumerable>。使用ToList會迭代序列,但是如果你想對每個元素執行一些操作,那麼你可以合併這些操作,通過一個重複的過程來做一個迭代,超級無瑕

0

非常有趣,沒有副作用和方法調用。

"TesteDessaBudega".Aggregate(new List<List<char>>(), 
(l, c) => char.IsUpper(c) ? 
    l.Union(
     new List<List<char>>(){ 
      new List<char>(){c} 
     } 
    ).ToList() : 
    l.Take(l.Count - 1).Union(
     new List<List<char>>(){ 
      l.Last().Union(
       new List<char>(){c} 
      ).ToList() 
     } 
    ).ToList() 
) 

哦,在vbnet只是爲了更好玩。

"TesteDessaBudega".Aggregate(New List(Of List(Of Char))(), 
Function(l, c) If(Char.IsUpper(c), 
    l.Union(
     New List(Of List(Of Char))(New List(Of Char)(){ 
      New List(Of Char)(New Char(){c}) 
     }) 
    ).ToList(), 
    l.Take(l.Count - 1).Union(
     New List(Of List(Of Char))(New List(Of Char)(){ 
      l.Last().Union(
       New List(Of Char)(New Char(){c}) 
      ).ToList() 
     }) 
    ).ToList() 
)) 

linqresult

+1

真的不確定這與問題有什麼關係。我有一種感覺,你正在回答一個不同的問題。 – btlog 2013-08-16 03:48:32