0

我过去曾使用它来构建逗号分隔列表:

var list = new List<int>{1,2,3};
var retVal = list.Select(i=>i.ToString()).Aggregate((a,b) => a+", "+b);

效果很好。

我正在尝试做同样的事情来将每个元素“包装”为一个 xml 节点。

就像是:

Aggregate((a, b) => string.Format("<ID>{0}</ID><ID>{1}</ID>", a,b))

似乎不能让它工作。可能吗?或者有没有更简单的方法?

谢谢。

4

4 回答 4

3

盲人的回答肯定会奏效,但我个人会使用:

var list = new List<int> {1, 2, 3};
var joined = string.Join("", list.Select(x => "<ID>" + x + "</ID>")
                                 .ToArray());

我个人觉得这比聚合更容易阅读和理解。我相信它也会更有效率——尽管这只对大型列表很重要。

于 2009-11-01T21:14:27.160 回答
3

或者有没有更简单的方法?

List<int> list = new List<int>{1, 2, 3};
var xmlNodes = list.Select(i => new XElement("ID", i));
XElement xml = new XElement("Data", xmlNodes);
Console.WriteLine(xml);
于 2009-11-02T13:02:10.990 回答
2

不应该是这样的:

Aggregate((a, b) => string.Format("{0}<ID>{1}</ID>", a,b))

您正在添加到a新节点。

于 2009-11-01T21:12:28.300 回答
0

有很多方法可以实现这一点,但我怀疑正确的答案是“视情况而定”。您创建 CSV 字符串的原始示例使用字符串连接运算符;推荐的方法是为此目的使用StringBuilder类。在 .Net 4.0 中有一个新的string.Join()方法重载,使用和理解要简单得多。

// .Net 3.5
var list = new List<int>{1,2,3};
var csv = list.Aggregate(new StringBuilder(), 
    (sb, i) => sb.Append(i).Append(','),
    sb => { if (sb.Length > 0) sb.Length--; return sb.ToString(); });

// .Net 4.0
var csv1 = string.Join(",", list);

如果您的意图是创建 XML 文档而不是字符串,那么上面David B的回答是一个不错的选择:

var xml = new XElement("Root", list.Select(i => new XElement("ID", i)));
// <Root>
//   <ID>1</ID>
//   <ID>2</ID>
//   <ID>3</ID>
// </Root> 

对于创建 XML 字符串,我更喜欢避免显式编码开始和结束标记。在您的示例中,很难在开始或结束标签中使元素名称“ID”不正确,但我认为这是根据 DRY 原则。有时我在修改开始标签时忘记修改元素的结束标签,例如在配置文件中。使用XElement完全避免了这个问题:

// .Net 3.5
var xml1 = list.Aggregate(new StringBuilder(), 
           (sb, i) => sb.Append(new XElement("ID", i)),
           sb => sb.ToString());

// .Net 4.0
var xml2 = string.Join("", list.Select (i => new XElement("ID", i)));
// both xml1 & xml2 contain "<ID>1</ID><ID>2</ID><ID>3</ID>"

Aggregate()string.Join()的性能,string.Join()每次都获胜(我使用的测试用例相当有限/基本)。

于 2010-07-09T05:06:01.033 回答