我有一个列表
List<string> sList = new List<string>() { "a","b","c"};
目前我正在选择以下结构的字典:
//(1,a)(2,b)(3,c)
Dictionary<int, string> dResult = new Dictionary<int, string>();
for(int i=0;i< sList.Count;i++)
{
dResult.Add(i, sList[i]);
}
但是对于Linq,我看到了ToDictionary((x,index) =>
正确的语法如何在一行内解决?
答案 0 :(得分:12)
您可以使用投影索引的Select
重载来填充匿名类型:
Dictionary<int, string> dResult = sList
.Select((s, index) => new { s, index })
.ToDictionary(x => x.index, x => x.s);
这与您的代码相同。如果您想要评论结果:(1,a)(2,b)(3,c)
),则必须添加+1 ToDictionary(x => x.index+1, x => x.s)
。
答案 1 :(得分:8)
没有ToDictionary
方法在一次调用中提供此方法,因为没有提供索引的重载,但您可以使用接受Select
的{{1}}重载:< / p>
Func<T, int, TResult>
或者在C#7中,避免使用var dictionary = list.Select((value, index) => new { value, index })
.ToDictionary(pair => pair.index, pair => pair.value);
创建一堆堆分配的对象:
ValueTuple
从C#7.1版本发布开始,您可以使用推断的var dictionary = list.Select((v, i) => (value: v, index: i))
.ToDictionary(pair => pair.index, pair => pair.value);
文字表达式:
ValueTuple
(如Tim所述,您需要将索引调整为1才能获得原始请求的输出。)
答案 2 :(得分:3)
首先,您必须使用select-overload获取密钥和值,该也会提供当前使用元素的索引:
var tmp = sList.Select((x, i) => new { Key = i, Value = x });
现在创建字典:
var result = tmp.ToDictionary(x => x.Key, x => x.Value);
或者作为一个单行:
var result = sList.Select((x, i) => new { Key = i, Value = x }).ToDictionary(x => x.Key, x => x.Value);
编辑:您还可以创建自己的扩展方法,以使用您提供的语法:
public static Dictionary<TResultKey, TResultValue> ToDictionary<TSource, TResultKey, TResultValue>(this IEnumerable<TSource> src, Func<TSource, int, TResultKey> KeySelector, Func<TSource, int, TResultValue> ValueSelector)
{
var result = new Dictionary<TResultKey, TResultValue>();
int i = 0;
foreach (var element in src)
{
result[KeySelector(element, i)] = ValueSelector(element, i);
i++;
}
return result;
}
现在你可以这样称呼它:
List<string> sList = new List<string>() { "a","b","c"};
var result = sList.ToDictionary((x, i) => i + 1, (x, i) => x);
答案 3 :(得分:3)
您也可以在没有匿名类型的情况下使用此方法:
Dictionary<int, string> dResult = Enumerable
.Range(0, sList.Count())
.ToDictionary(i => i + 1, i => sList[i]);