У меня есть список
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) =>
Как правильный синтаксис или как это решить в одной строке?
4 ответа
Вы можете использовать перегрузку 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)
.
Не существует метода ToDictionary
, который давал бы это за один вызов, поскольку нет перегрузок, предоставляющих индекс, но вы можете использовать перегрузку Select
, которая принимает Func<T, int, TResult>
:
var dictionary = list.Select((value, index) => new { value, index })
.ToDictionary(pair => pair.index, pair => pair.value);
Или в C # 7, избегая создания группы объектов, размещенных в куче, используя ValueTuple
:
var dictionary = list.Select((v, i) => (value: v, index: i))
.ToDictionary(pair => pair.index, pair => pair.value);
Начиная с версии C # 7.1, вы можете использовать логическое выражение ValueTuple
:
var dictionary = list.Select((value, index) => (value, index))
.ToDictionary(pair => pair.index, pair => pair.value);
(Как отметил Тим, вам нужно изменить индекс на 1, чтобы получить исходный запрошенный результат.)
Сначала вам нужно получить ключ и значение с помощью select-overload a>, который также проверяет индекс текущего используемого элемента:
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);
Вы также можете использовать этот подход без анонимного типа:
Dictionary<int, string> dResult = Enumerable
.Range(0, sList.Count())
.ToDictionary(i => i + 1, i => sList[i]);
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.