2016-09-26 98 views
1

我有此ToString用於寫出對象的方法。我試圖將for循環轉換爲foreach循環。 不使用LINQ。轉換爲循環以索引爲foreach

任何指針將不勝感激。

public override string ToString() 
{ 
    StringBuilder output = new StringBuilder(); 
    output.AppendFormat("{0}", count); 
    for (var index = 0; index < total; index++) 
    { 
     output.AppendFormat("{0}{1}{2} ", array[index], array[index].GetInfo, 
           string.Join(" ", array[index].Content(index)), 
          ); 
    } 
    return output.ToString(); 
} 
+0

爲什麼近距離投票,因爲這太寬? –

+0

好吧,爲什麼downvote?這個世界如何過於廣泛? – hello

+1

[mcve]在這裏很有用。 – Enigmativity

回答

2

這是根據您當前的代碼進行的重構。

public override string ToString() { 
    var output = new StringBuilder(); 
    output.AppendFormat("{0}", count); 
    var index = 0; 
    foreach (var item in array) { 
     if (item!=null) { 
      output.AppendFormat("{0}{1}{2} ", item, item.GetInfo, 
           string.Join(" ", item.Content(index++)), 
          ); 
     } 
    } 
    return output.ToString(); 
} 

使用LINQ,你可以不直接調用它的引擎蓋下使用

public override string ToString() { 
    var output = new StringBuilder(); 
    output.AppendFormat("{0}", count); 
    array.Select((item, index) => 
     output.AppendFormat("{0}{1}{2} ", item, item.GetInfo, 
           string.Join(" ", item.Content(index)), 
          ) 
    ); 
    return output.ToString(); 
} 
+0

感謝您的回答。如果我不想通過'array'的所有內容,因爲它有些是空的。是否有可能突破每個 – hello

+0

你可以過濾只採取不是'null'的項目。即'array.Where(item => item!= null)' – Nkosi

+0

我對此表示歉意,LINQ對我來說不是一種選擇。 – hello

2

技術上在foreach執行與索引Select一樣的,你可以做這樣的事情:

public override string ToString() 
{ 
    StringBuilder output = new StringBuilder(); 
    output.Append(count); 

    int index = 0; 
    foreach (var item in array) 
    {   
     output.Append($"{item}{item.GetInfo()}{string.Join(" ", item.Content(index))}"); 
     index++; 
    } 
    return output.ToString(); 
} 

總之,無論如何,你要去int index。根據performance,將它移到foreach並不是很有幫助。

如果您真的不喜歡在任何地方編寫增量索引,您也可以嘗試使用自己的ForEach擴展。

public static class EnumerableExtensions 
{ 
    public static void ForEachWithIndex<T>(this IEnumerable<T> sequence, Action<int, T> action) 
    { 
     // argument null checking omitted 
     int i = 0; 
     foreach (T item in sequence) 
     { 
      action(i, item); 
      i++; 
     } 
    } 
} 

然後你的方法會更簡單,但你必須多一個類來管理:

public override string ToString() 
{ 
    StringBuilder output = new StringBuilder(); 
    output.Append(count); 
    array.ForEachWithIndex((index, item) => output.Append($"{item}{item.GetInfo()}{string.Join("", item.Content(index))}")); 
    return output.ToString(); 
} 

而對於可讀性,如果你真的只是把字符串並排:

public override string ToString() 
{ 
    StringBuilder output = new StringBuilder(); 
    output.Append(count); 
    array.ForEachWithIndex((index, item) => output.Append(
     string.Concat(
      item, 
      item.GetInfo(), 
      string.Join("", item.Content(index)) 
      ))); 
    return output.ToString(); 
} 

由於string.Concat無論如何都會更加明顯表現明智。如果您需要格式化,請選擇其他人。

+0

謝謝你。這也行得通,但我必須接受第一個出現的那個。 – hello

+2

這很好。謝謝。 –

2

根據什麼totalcount是,你可以重構的東西是這樣的:

public override string ToString() 
{ 
    return count.ToString() 
     + String.Join(" ", 
      array.Select((x, n) => $"{x}{x.GetInfo}{String.Join(" ", x.Content(n))}")); 
} 

String.Join往往可以表現得比較好StringBuilder,所以它不是一個壞的選擇。


你走了。沒有LINQ這個擴展需要:

public static class Ex 
{ 
    public static IEnumerable<R> Select<T, R>(this IEnumerable<T> source, Func<T, int, R> projection) 
    { 
     int index = 0; 
     foreach (var item in source) 
     { 
      yield return projection(item, index++); 
     } 
    } 
} 
+0

LINQ不適合我。對不起,最初沒有在問題中說過。 – hello

+1

@hello - 我已經給你一個非LINQ解決方案。 – Enigmativity