这个问题多年来一直困扰着我,而且当我有一个更好的解决方案时,我总觉得我想要一个黑客。当您想要对列表中的所有项目执行某些操作然后在
例如,假设我有一个名为Equation
的课程:
public class Equation
{
public string LeftSide { get; set; }
public string Operator { get; set; }
public string RightSide { get; set; }
}
我想迭代一个Equation
列表并返回一个将这些项格式化在一起的字符串;如下所示:
public string FormatEquationList(List<Equation> listEquations)
{
string output = string.Empty;
foreach (Equation e in listEquations)
{
//format the Equation
string equation = "(" + e.LeftSide + e.Operator + e.RightSide + ")";
//format the "inbetween" part
string inbetween = " and ";
//concatenate the Equation and "inbetween" part to the output
output += equation + inbetween;
}
return ouput;
}
上面代码的问题是它将在返回的字符串的末尾包含and
。我知道我可以一起破解一些代码,用foreach
循环替换for
,只有当inbetween
元素不是最后一项时才添加{{1}}元素;但这似乎是一个黑客。
有没有一种标准方法可以解决这类问题?
答案 0 :(得分:8)
您基本上有一些不同的策略来处理此类问题:
这些选项中的任何一个都可以是实现“项目之间”算法风格的合法方式。您选择哪一个取决于:
除此之外。对于字符串的特定情况,我个人更喜欢使用string.Join()
,因为我发现它最清楚地说明了意图。此外,对于字符串,如果您不使用string.Join()
,则应尝试使用StringBuilder
以避免创建过多的临时字符串(字符串在.Net中不可变的结果)。< / p>
使用字符串连接作为示例,不同的选项分解为示例,如下所示。 (为简单起见,假设公式为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()
进行字符串连接,因为它会产生许多中间的,丢弃的字符串。它也不是将一堆结果“加入”在一起的最明显的方式 - 它主要用于以某种随意,调用者定义的方式计算集合的“标量”结果。
答案 1 :(得分:6)
您可以使用String.Join()。
String.Join(" and ",listEquations.Select(e=>String.Format("({0}{1}{2})",e.LeftSide,e.Operator,e.RightSide).ToArray());
答案 2 :(得分:3)
您可以使用LINQ的Aggregate
运算符执行此操作:
public string FormatEquationList(List<Equation> listEquations)
{
return listEquations.Aggregate((a, b) =>
"(" + a.LeftSide + a.Operator + a.RightSide + ") and (" +
b.LeftSide + b.Operator + b.RightSide + ")");
}
答案 3 :(得分:2)
如果您不想要for
循环,则使用带计数器的foreach
循环是完全合理的。这就是为什么有多种类型的循环语句。
如果要成对处理项目,请在LINQ的Aggregate
运算符处循环。
答案 4 :(得分:2)
我通常在条件之前添加它,并检查它是否是第1项。
public string FormatEquationList(List<Equation> listEquations)
{
string output = string.Empty;
foreach (Equation e in listEquations)
{
//use conditional to insert your "between" data:
output += (output == String.Empty) ? string.Empty : " and ";
//format the Equation
output += "(" + e.LeftSide + e.Operator + e.RightSide + ")";
}
return ouput;
}
我不得不说我会查看string.Join()函数,对于Linqiness来说就是+1。我的例子是一个传统的解决方案。
答案 5 :(得分:1)
我通常会尝试根据条件为分隔符添加前缀,而不是将它们添加到结尾。
string output = string.Empty;
for (int i = 0; i < 10; i++)
{
output += output == string.Empty ? i.ToString() : " and " + i.ToString();
}
0和1和2和3以及4和5以及6和7以及8和9
答案 6 :(得分:1)
我喜欢已发布的String.Join方法。
但是当你不使用数组时,这通常是我解决这个问题的方法:
public string FormatEquationList(List<Equation> listEquations)
{
string output = string.Empty;
foreach (Equation e in listEquations)
{
// only append " and " when there's something to append to
if (output != string.Empty)
output += " and ";
output += "(" + e.LeftSide + e.Operator + e.RightSide + ")";
}
return output;
}
当然,使用StringBuilder通常会更快:
public string FormatEquationList(List<Equation> listEquations)
{
StringBuilder output = new StringBuilder();
foreach (Equation e in listEquations)
{
// only append " and " when there's something to append to
if (output.Length > 0)
output.Append(" and ");
output.Append("(");
output.Append(e.LeftSide);
output.Append(e.Operator);
output.Append(e.RightSide);
output.Append(")");
}
return output.ToString();
}