Visual C#的集合“map”函数是什么?

8
在Haskell中,我们有一个函数

map (a -> b) -> [a] -> [b]

使用函数更改集合的类型。

C# 中有类似的东西吗?

或者说,将一个完整的 KeyValuePair 集合放入调试信息中的最快方法是什么?

我想到了这样的代码:

debugmsg("http response is " + service.HttpResponseHeaders
                                      .Map<string>((k, v) => k + "->" + v)
                                      .Aggregate((s, sx) => s + "," + sx)
                             + ". ");

请注意,一个头可以有多个值。简单地连接这些值是行不通的。 - Panagiotis Kanavos
5个回答

13

在LINQ中,map被命名为Select。另外,请注意任何KeyValuePair<TKey, TValue>的集合在Select中只有一个参数;你需要从中提取出KeyValue

service.HttpResponseHeaders.Select(kvp => kvp.Key + "->" + kvp.Value)
                           .Aggregate((s, sx) => s + "," + sx);

值是一个IEnumerable<string>。简单地连接字符串将导致"String[]"而不是实际值。 - Panagiotis Kanavos
如果key-value对中的Value是一个集合,那么在该值上执行SelectMany(又称为flatMap)应该可以解决这个问题。 - Patryk Ćwiek
不是的,你需要将单个标题名称与多个值结合起来。单个操作是不够的。 - Panagiotis Kanavos
kvp => kvp.Key + "->" + string.Join("-", kvp.Value) 应该就足够了。不过问题是关于 map 的... - Patryk Ćwiek

1
LINQ自带Select
签名(Haskell风格):
IEnumerable<TSource>.Select(Func<TSource->TResult>)->IEnumerable<TResult>

1
你可以使用 Dictionary,它基本上是一个由 KeyValuePair 组成的集合,然后执行以下操作:
service.HttpResponseHeaders
                  .Select(kvp => kvp.Key + " -> " + String.Join(" - ", kvp.Value))
                  .Aggregate((s, sx) => s + ", " + sx);

优化聚合:优化字符串拼接的聚合


HttpResponseHeaders 也是一个 KeyValuePair 集合,实际上它实现了 IEnumerable<KeyValuePair<string, IEnumerable<string>>> 接口。不需要使用 Dictionary,而字符串拼接将返回 "String[]" 而非头部值。 - Panagiotis Kanavos
然后在你的值上调用.Aggregate()。看一下我的编辑。 - Florian Gl
使用String.Join会更简单和更快,因为它不会创建任何临时字符串。 - Panagiotis Kanavos
你确定 .Aggregate() 做了什么?为什么它不应该也使用 StringBuilder - Florian Gl
除了DRY(不要重复自己)原则,就是试一下看看它有多丑。 - Panagiotis Kanavos
在我看来,调用.Aggregate()两次不会违反DRY原则。而且结果与使用String.Join()相同。 - Florian Gl

1
正如其他人所指出的那样,您可以使用Select将一种类型映射到另一种类型。但是,最好使用String.Join创建最终字符串,以避免创建无用的临时字符串。
.NET中的字符串是不可变的,因此添加两个字符串会创建一个新的字符串。另一方面,String.Join在内部使用StringBuilder将数据添加到可变缓冲区并返回最终结果。
但是,请注意HttpResponseHeaders包含每个键的多个值。仅将值转换为字符串将无法正常工作。
以下代码将从响应标头创建逗号分隔的值列表。如果标头有多个值,则它们用竖线分隔:
var headerStrings=from header in service.HttpResponseHeaders
            let headerValue=String.Join("|",header.Value)
            select String.Format("{0} -> {1}",header.Key,headerValue);
var message=String.Join(",",headerStrings);

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接