Чтение онлайн

ЖАНРЫ

C# 4.0 полное руководство - 2011

Шилдт Герберт

Шрифт:

содержащий пару символов, которые сохраняются в переменных chi и ch2 на каждом шаге циклического обращения к массиву во внутреннем операторе from. А в конечном итоге получается объект типа ChrPair, содержащий все возможные сочетания извлекаемых символов.

Вложенные'операторы from применяются также для циклического обращения к источнику данных, который содержится в другом источнике данных. Соответствующий пример приведен в разделе "Применение оператора let для создания временной переменной в запросе" далее в этой главе.

Группирование результатов с помощью оператора group

Одним

из самых эффективных средств формирования запроса является оператор
group, поскольку он позволяет группировать полученные результаты по ключам. Используя последовательность сгруппированных результатов, можно без особого труда получить доступ ко всем данным, связанным с ключом. Благодаря этому свойству оператора group доступ к данным, организованным в последовательности связанных элементов, осуществляется просто и эффективно. Оператор group является одним из двух операторов, которыми может оканчиваться запрос. (Вторым оператором, завершающим запрос, является select.) Ниже приведена общая форма оператора group.

group переменная_диапазона by ключ

Этот оператор возвращает данные, сгруппированные в последовательности, причем каждую последовательность обозначает общий ключ.

Результатом выполнения оператора group является последовательность, состоящая из элементов типа IGrouping<TKey, TElement>, т.е. обобщенного интерфейса, объявляемого в пространстве имен System. Linq. В этом интерфейсе определена коллекция объектов с общим ключом. Типом переменной запроса, возвращающего группу, является IEnumerable<IGrouping<TKey, TElement>>. В интерфейсе IGrouping определено также доступное только для чтения свойство Key, возвращающее ключ, связанный с каждой коллекцией.

Ниже приведен пример, демонстрирующий применение оператора group. В коде этого примера сначала объявляется массив, содержащий список веб-сайтов, а затем формируется запрос, в котором этот список группируется по имени домена самого верхнего уровня, например . org или . сот.

// Продемонстрировать применение оператора group.

using System; using System.Linq;

class GroupDemo {

static void Main {

string[] websites = { "hsNameA.com", "hsNameB.net", "hsNameC.net", "hsNameD.com", "hsNameE.org", "hsNameF.org",

"hsNameG.tv", "hsNameH.net", "hsNamel.tv"

};

// Сформировать запрос на получение списка веб-сайтов,

// группируемых по имени домена самого верхнего уровня.

var webAddrs = from addr in websites

where addr.LastlndexOf('.') != -1

group addr by addr.Substring(addr.LastlndexOf('.'));

// Выполнить запрос и вывести его результаты, foreach(var sites in webAddrs) {

Console.WriteLine("Веб-сайты, сгруппированные " +

"по имени домена" + sites.Key); foreach(var site in sites)

Console.WriteLine (" " + site);

Console.WriteLine;

}

}

}

Вот к какому результату приводит выполнение этого кода.

Веб-сайты, сгруппированные по имени домена .сот

hsNameA.сот hsNameD.сот

Веб-сайты, сгруппированные по имени домена .net hsNameB.net hsNameC.net

hsNameH.net *

Веб-сайты, сгруппированные по имени домена .org hsNameE.org hsNameF.org

Веб-сайты, сгруппированные по имени домена .tv hsNameG.tv hsNamel.tv

Как следует из приведенного

выше результата, данные, получаемые по запросу, группируются по имени домена самого верхнего уровня в адресе веб-сайта. Обратите внимание на то, как это делается в операторе
group из следующего запроса.

var webAddrs = from addr in websites

where addr.LastlndexOf('.') != -1

group addr by addr.Substring(addr.LastlndexOf('.'));

Ключ в этом операторе создается с помощью методов LastlndexOf и Substring , определенных для данных типа string. (Эти методы упоминаются в главе 7, посвященной массивам и строкам. Вариант метода Substring , используемый в данном примере, возвращает подстроку, начинающуюся с места, обозначаемого индексом, и продолжающуюся до конца вызывающей строки.) Индекс последней точки в адресе веб-сайта определяется с помощью метода LastlndexOf . По этому индексу в методе Substring создается оставшаяся часть строки, в которой содержится имя домена самого верхнего уровня. Обратите внимание на то, что в операторе where отсеиваются все строки, которые не содержат точку. Метод LastlndexOf возвращает -1, если указанная подстрока не содержится в вызывающей строке.

Последовательность результатов, получаемых при выполнении запроса, хранящегося в переменной webAddrs, представляет собой список групп, поэтому для доступа к каждому члену группы требуются два цикла foreach. Доступ к каждой группе осуществляется во внешнем цикле, а члены внутри группы перечисляются во внутреннем цикле. Переменная шага внешнего цикла foreach должна быть экземпляром интерфейса I Grouping, совместимым с ключом и типом элемента данных. В рассматриваемом здесь примере ключи и элементы данных относятся к типу string. Поэтому переменная sites шага внешнего цикла имеет тип IGrouping<string, string>, а переменная site шага внутреннего цикла — тип string. Ради краткости данного примера обе переменные объявляются неявно, хотя их можно объявить и явным образом, как показано ниже.

foreach(IGrouping<string, string> sites in webAddrs) {

Console.WriteLine("Веб-сайты, сгруппированные " +

"по имени домена" + sites.Key); foreach(string site in sites)

Console.WriteLine(" " + site);

Console.WriteLine ;

}

Продолжение запроса с помощью оператора into

При использовании в запросе оператора select или group иногда требуется сформировать временный результат, который будет служить продолжением запроса для получения окончательного результата. Такое продолжение осуществляется с помощью оператора into в комбинации с оператором select или group. Ниже приведена общая форма оператора into:

into имя тело_запроса

где имя обозначает конкретное имя переменной диапазона, используемой для циклического обращения к временному результату в продолжении запроса, на которое указывает тело_запроса. Когда оператор into используется вместе с оператором select или group, то его называют продолжением запроса, поскольку он продолжает запрос. По существу, продолжение запроса воплощает в себе принцип построения нового запроса по результатам предыдущего.

Поделиться с друзьями: