Basically, you have several different strategies to solve this problem:
- Process the first (or last) element outside the loop.
- Do the work, and then undo the extraneous step.
- Determine that you are processing the first or last element inside the loop.
- Use a higher level abstraction that avoids the situation.
Any of these parameters can be a legitimate way to implement the "between elements" style of the algorithm. Which one you choose depends on such things as:
- what style do you like
- how expensive is the "cancel the job"
- how expensive is the step to "join"
- are there any side effects
Among other things. For the particular case of the string, I personally prefer to use string.Join() , as I find it most clearly illustrates the intention. Also, in the case of strings, if you are not using string.Join() , you should try to use StringBuilder to avoid creating too many temporary strings (a consequence of immutable strings in .Net).
As an example, we use string concatenation; various variants are divided into examples as follows. (For simplicity, suppose the equation has ToString() as: "(" + 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(); }
The second option looks like this:
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 ); }
The third will look something like this:
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 ); } }
The last option can take several forms in .NET using either String.Join or Linq:
public string FormatEquation( IEnumerable<Equation> listEquations ) { return string.Join( " and ", listEquations.Select( eq => eq.ToString() ).ToArray() ); }
or
public string FormatEquation( IEnumerable<Equation> listEquations ) { return listEquations.Aggregate((a, b) => a.ToString() + " and " + b.ToString() ); }
Personally, I don't use Aggregate() to concatenate strings, because this leads to a lot of intermediate, discarded strings. This is also not the most obvious way to "combine" a set of results together - it is primarily intended to calculate the "scalar" results from the collection in some arbitrary way defined by the caller.