Разница между возвращаемыми значениями двух функций селектора в этом коде
var Students = new Dictionary<string, int>();
Students.Add( "Bob" , 60);
Students.Add( "Jim" , 62);
Students.Add( "Jack", 75);
Students.Add( "John", 81);
Students.Add( "Matt", 60);
Students.Add( "Jill", 72);
Students.Add( "Eric", 83);
Students.Add( "Adam", 60);
Students.Add( "Gary", 75);
var MyVar = Students.GroupBy(r=> r.Value)
.ToDictionary(t=> t.Key, t=> t.Select(x=> x.Key));
Students
объект имеет Name
а также Weight
пары ключ-значение.
В методе ToDictionary, t
переменная имеет тип IEnumerable<IGrouping<K, T>>
, То есть, IEnumerable<IGrouping<int, Students>>
Почему Key
значения, возвращаемые t=>t.Key
а также t=> t.Select(**x=> x.Key**)
разные? Они оба используют один и тот же t
переменная. Key
должен быть типа int
,
Изображение было снято после того, как был выполнен метод GroupBy. (Это не полное изображение) Один из Key
имеет значение 60
а другой имеет значения Bob
, Matt
а также Adam
,
4 ответа
Потому что это не
IEnumerable<IGrouping<int, Student>>
Это
IEnumerable<IGrouping<int, KeyValuePair<int, Student>>>
В t => t.Key
Вы имеете в виду ключ группировки, и в Select(x => x.Key)
вы имеете в виду KeyValuePair
,
Вы можете навести курсор на переменные в Visual Studio, чтобы увидеть типы и параметры типов.
Более подробно:
// return an IEnumerable<IGrouping<int, KeyValuePair<int, Student>>>
Students.GroupBy(r=> r.Value)
// iterate over each IGrouping<int, KeyValuePair<int, Student>>
.ToDictionary(
group => group.Key,
// iterate over each KeyValuePair<int, Student> in the group
// because IGrouping<TKey, TElement> inherits from IEnumerable<TElement>
// so it's a Select over an IEnumerable<KeyValuePair<int, Student>>
group => group.Select(pair => pair.Key));
Он создает новый словарь с номером в качестве ключа и всеми именами учащихся из исходного словаря, связанными с определенным ключом.
Вот как это работает.
Почему значения ключей возвращаются
t=>t.Key
Это работает над GroupBy
, поскольку GroupBy
применяется на Value
, который int
в оригинальном словаре. Таким образом, новый словарь будет иметь различные ключи, основанные на значениях исходного словаря.
и t => t.Select (x => x.Key) разные?
Теперь это Select
работает на каждом GroupBy
элемент из оригинального словаря. куда Key
это имя студента. Таким образом, получая все имена студентов на основе Key
выбранный ранее в GroupBy
Это то, что результат Students.GroupBy(r => r.Value)
похоже. Это немного сбивает с толку, так как оба GroupBy
так же как Dictionary
использовать Key
,
{ (Key = 60, {(Key = "Bob", Value = 60), (Key = "Matt", Value = 60), ...}),
(Key = 62, {(Key = "Jim", Value = 62)}),
(Key = 72. ...),
...
}
t
один ряд этой группировки.
Первый селектор t.Key
доходность 60
,
Второй селектор t.Select(x => x.Key)
работает в списке и дает {"Bob", "Matt", "Adam"}
,
Key
из IGrouping
(t.Key
) - это ключ, на котором вы сгруппированы GroupBy
, В этом случае это Value
из KeyValuePair
,
Ключ в пределах Select
(x.Key
) получает ключ KeyValuePair
для каждой пары в группе.
Это несколько менее очевидно здесь из-за предполагаемых типов, но вы можете навести курсор на оба x
а также t
в визуальной студии, чтобы увидеть, что t
является IGrouping
а также x
это KeyValuePair
, Вы также можете улучшить ясность этого запроса (на мой взгляд, немного), используя более значимые имена переменных.
var MyVar = Students.GroupBy(pair => pair.Value)
.ToDictionary(group => group.Key,
group => group.Select(pair => pair.Key));