将 for 循环转换为带索引的 foreach
convert for loop to foreach with index
我有这个ToString
方法用来写出对象。我正在尝试将 for
循环转换为 foreach
循环。
不使用 LINQ。
任何指点将不胜感激。
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();
}
这里是基于您当前代码的重构。
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,您可以使用索引 Select
执行相同的操作,而无需直接调用后台使用的 foreach
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();
}
从技术上讲,您可以这样做:
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++;
}
}
}
那么你的方法会更简单,但你还有一个 class 需要管理:
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();
}
As string.Concat
无论如何,在性能方面会更受欢迎。如果您需要格式化,请选择其他选项。
根据 total
和 count
是什么,您可以重构为如下内容:
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++);
}
}
}
我有这个ToString
方法用来写出对象。我正在尝试将 for
循环转换为 foreach
循环。
不使用 LINQ。
任何指点将不胜感激。
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();
}
这里是基于您当前代码的重构。
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,您可以使用索引 Select
执行相同的操作,而无需直接调用后台使用的 foreach
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();
}
从技术上讲,您可以这样做:
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++;
}
}
}
那么你的方法会更简单,但你还有一个 class 需要管理:
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();
}
As string.Concat
无论如何,在性能方面会更受欢迎。如果您需要格式化,请选择其他选项。
根据 total
和 count
是什么,您可以重构为如下内容:
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++);
}
}
}