从多个格式的数值中创建逗号分隔的字符串
我使用逗号分隔值列表创建了一个字符串,但这些数字值具有不同的格式。目前我使用的是这样的:从多个格式的数值中创建逗号分隔的字符串
var values = new StringBuilder();
// These are all of type double
values.AppendFormat("{0:F1},", aLength);
values.AppendFormat("{0:F4},", anAngle);
values.AppendFormat("{0:F1},", aHeight);
values.AppendFormat("{0:F2},{1:F2},", a2DPoint.X, a2DPoint.Y);
// while these are all of type int
values.Append(anID).Append(",");
values.Append(anInt).Append(",");
values.Append(anotherInt);
if (aListOfInt.Count > 0)
{
values.Append(",");
values.Append(String.Join(",", aListOfInt));
}
var resultString = values.ToString();
这是正确的方法吗?我也可以用String.Join这样做,事先创建一个类似于上面的StringBuilder values
的List<string>
,但是会更好吗? 有没有更优雅的方式?
注:我是新来的C#
我觉得这确实是相当不错:
var resultString = String.Join(",", new []
{
aLength.ToString("F1"),
anAngle.ToString("F4"),
aHeight.ToString("F1"),
a2DPoint.X.ToString("F2"),
a2DPoint.Y.ToString("F2"),
anID.ToString(),
anInt.ToString(),
anotherInt.ToString(),
}.Concat(aListOfInt.Select(x => x.ToString())));
试试这个:
var objList = new List<object>();
objList.Add(1);
objList.Add(2.0);
...
var resultString = string.Join(",", objList.Cast<string>());
把自己的价值观对象的列表,施放值的字符串,并加入值。
但与上述你将失去你的格式。 我有另一种解决方案。我认为这是没有松动的每个值的格式很短的语法:
var stringList = new List<string>{
aLength.ToString("F1"),
anAngle.ToString("F4"),
...
};
var resultString = string.Join(",", stringList);
这对于不同格式的值有什么帮助?即有些人用'F2''别人用'F2'还有其他人用'F4'等等? – Corak 2014-09-04 07:41:06
请参阅第二节。我在同一时间看到了我的错误。首先我想你是指double和int的混合。 – 2014-09-04 07:49:02
@MathiasMüller你的第二部分是我说的“我也可以用'String.Join'来做到这一点”,而不是建立一个'StringBuilder'列表,建立一个'List
如果你在寻找什么是更优雅(而不是最优的),你可以尝试这样的事:
//Note the commas in the formats,and that formats and data have the same size.
List<string> formats = new List<string>(new string[] {"{0:F1},", "{0:F4},", "{0:F2},",{0}});
List<object> data=new List<object>(new object[]{4,2,0.12,new object()});
StringBuilder resultBuilder=new StringBuilder();
for (int i = 0; i < 4; i++) {
resultBuilder.AppendFormat(formats[i], data[i]);
}
string result = resultBuilder.ToString();
只要您对如何设置格式和数据非常小心,除了for循环之外,您无需执行任何其他处理即可将它们“压缩”在一起。我建议在任何a2DPoint类上重写ToString(),这样你就可以将它放到一个单独的格式块中,而不需要特殊的处理,或者将a2DPoint.X和a2DPoint.Y拆分成单独的数据/格式块。不过,这不是最有效的方法。列表占用了空间和时间;如果你提前知道你会有多少条目,阵列可能会更好。
编辑:在注释方法的实施 编辑:添加例子方法的评论称:
public class FormatZipper {
//This could be two lists, but it's probably more space/time efficent to use a single list.
List<Tuple<string,object>> _entries;
StringBuilder _builder;
public FormatZipper() {
_builder = new StringBuilder();
_entries = new List<Tuple<string, object>>();
}
public void AddEntry(string fmt, object data) {
_entries.Add(Tuple.Create(fmt, data));
}
public string CurrentString {
get {
_builder.Clear();
foreach (var entry in _entries) {
_builder.AppendFormat(entry.Item1, entry.Item2);
}
return _builder.ToString();
}
}
}
class Program {
static void Main(string[] args) {
FormatZipper zipper = new FormatZipper();
zipper.AddEntry("{0:F1},", 1);
Console.WriteLine(zipper.CurrentString);
zipper.AddEntry("{0:F2,", 1);
Console.WriteLine(zipper.CurrentString);
}
}
尽管看起来很有趣,但这个解决方案的问题在于,正如您所说的,您需要非常小心地设置格式和数据,否则很容易导致不匹配。 – alondono 2014-09-04 11:11:28
您可以通过将两个列表翘曲成只允许同时添加值和格式的单个类(即formatZipper.AddField(string fmt,object data))来解决此问题。然后,您可以通过覆盖ToString()或提供某种方法或属性来运行for循环。这样做有更复杂的方法,但他们需要更多关于具体细节的知识。 – Benjamin 2014-09-04 17:02:11
我很欣赏你的努力,但是它开始看起来有点复杂吗?无论如何,我喜欢你对这两个列表的想法。 – alondono 2014-09-05 01:12:57
使用了逗号分隔的字符串十进制数字是一个坏主意 - 有很多文化在他们的数字中使用逗号,这是造成问题的常见原因。例如,可以使用逗号来分隔数千个,甚至是小数点。当转换成字符串和字符串时,至少使用'CultureInfo.InvariantCulture',否则你刚刚破坏了你的应用程序半个星球:) – Luaan 2014-09-04 07:28:01
@Luaan啊,这是一个很好的观点。在这种特殊情况下,这是正在写入文件的信息,用于与旧系统的向后兼容,而旧系统甚至用不同的语言编写。我们正试图改变事情的方式。但是你的评论是我们应该考虑的事情。感谢那。 – alondono 2014-09-04 11:03:09
我认为最好的实现方法是为每个度量单位(即长度,角度,点)创建一个类并覆盖它们的ToString方法,并让多态性为您工作。至于加入这些值,string.Join是最干净的选项。 – brz 2014-09-04 18:41:27