У вас есть несколько разных стратегий для решения этой проблемы:
- Обработка первого (или последнего) элемента вне цикла.
- Выполните работу, а затем «отмените» посторонний шаг.
- Определите, что вы обрабатываете первый или последний элемент внутри цикла.
- Используйте абстракцию более высокого уровня, которая позволяет избежать ситуации.
Любой из этих параметров может быть легитимным способом реализации алгоритма в стиле «между элементами». Какой из них вы выберете, зависит от таких вещей, как:
- какой стиль тебе нравится
- как дорого стоит "уничтожающая работа"
- сколько стоит каждый шаг "соединения"
- есть ли побочные эффекты
Среди прочего. Для конкретного случая строки я лично предпочитаю использовать string.Join()
, так как считаю, что это наиболее четко иллюстрирует цель. Кроме того, в случае строк, если вы не используете string.Join()
, вы должны попытаться использовать StringBuilder
, чтобы избежать создания слишком большого количества временных строк (следствие того, что строки являются неизменяемыми в .Net).
Используя конкатенацию строк в качестве примера, различные параметры делятся на примеры следующим образом. (Для простоты предположим, что уравнение имеет ToString()
как: "(" + LeftSide + Operator + RightSide + ")"
public string FormatEquation( IEnumerable<Equation> listEquations )
{
StringBuilder sb = new StringBuilder();
if( listEquations.Count > 0 )
sb.Append( listEquations[0].ToString() );
for( int i = 1; i < listEquations.Count; i++ )
sb.Append( " and " + listEquations[i].ToString() );
return sb.ToString();
}
Второй вариант выглядит так:
public string FormatEquation( IEnumerable<Equation> listEquations )
{
StringBuilder sb = new StringBuilder();
const string separator = " and ";
foreach( var eq in listEquations )
sb.Append( eq.ToString() + separator );
if( listEquations.Count > 1 )
sb.Remove( sb.Length, separator.Length );
}
Третий будет выглядеть примерно так:
public string FormatEquation( IEnumerable<Equation> listEquations )
{
StringBuilder sb = new StringBuilder();
const string separator = " and ";
foreach( var eq in listEquations )
{
sb.Append( eq.ToString() );
if( index == list.Equations.Count-1 )
break;
sb.Append( separator );
}
}
Последний вариант может принимать несколько форм в .NET, используя либо String.Join, либо Linq:
public string FormatEquation( IEnumerable<Equation> listEquations )
{
return string.Join( " and ", listEquations.Select( eq => eq.ToString() ).ToArray() );
}
или
public string FormatEquation( IEnumerable<Equation> listEquations )
{
return listEquations.Aggregate((a, b) => a.ToString() + " and " + b.ToString() );
}
Лично я избегаю использования Aggregate()
для конкатенации строк, потому что это приводит к множеству промежуточных, отброшенных строк. Это также не самый очевидный способ «объединить» кучу результатов вместе - он в первую очередь предназначен для вычисления «скалярных» результатов из коллекции произвольным, определенным вызывающим способом.