Разница между возвращаемыми значениями двух функций селектора в этом коде

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));
Другие вопросы по тегам