Programming Taskbook 0
Download 1.62 Mb. Pdf ko'rish
|
Abramyan-Pascal2016-1
- Bu sahifa navigatsiya:
- [(10,40),(10,60),(21,51),(33,53)]
- [(10,[40,60]),(21,[51]),(33,[53]),(84,[])]
Глава 4. Запросы 79 ся число) и возвращая последовательность пар чисел (каждая пара пред- ставляется в виде кортежа): var res := a1.Join(a2, e1 -> e1 mod 10, e2 -> e2 mod 10, (e1, e2) -> (e1, e2)); Write(res); // [(10,40),(10,60),(21,51),(33,53)] Если мы заменим в предыдущем фрагменте имя запроса на GroupJoin, не меняя его параметры, то мы тоже получим последовательность пар, но теперь вторым элементом каждой пары будет последовательность (всех элементов a2, имеющих одинаковый ключ с первым элементом этой же пары): var res := a1.GroupJoin(a2, e1 -> e1 mod 10, e2 -> e2 mod 10, (e1, e2) -> (e1, e2)); Write(res); // [(10,[40,60]),(21,[51]),(33,[53]),(84,[])] Мы видим, что в данном случае второе поле каждого кортежа является последовательностью. Обратите внимание на то, что с элементом 84 свя- зывается пустая последовательность, поскольку в последовательности a2 отсутствуют числа, оканчивающиеся на 4 (по этой же причине элемент 84 отсутствовал в последовательности, построенной с помощью запроса Join). Итак, запрос Join формирует «плоское» внутреннее объединение (с каждым элементом внешней последовательности в полученном объеди- нении связывается по одному элементу внутренней), тогда как внешнее объединение, формируемое запросом GroupJoin, является иерархическим (с каждым элементом внешней последовательности связывается последо- вательность элементов внутренней). В некоторых ситуациях требуется сформировать плоское левое внешнее объединение, которое отличается от внутреннего объединения только тем, что включает все элементы внешней последовательности — в том числе и те, для которых не нашлось пары во внутренней последовательности (подобные элементы в плоском левом внешнем объединении объединяются в пару с каким-либо особым значе- нием, например нулем). Поскольку для преобразования иерархической последовательности в плоскую предназначен запрос SelectMany, естественно использовать для по- строения плоского левого внешнего объединения комбинацию запросов GroupJoin и SelectMany: var res := a1.GroupJoin(a2, e1 -> e1 mod 10, e2 -> e2 mod 10, (e1, e2) -> e2.Select(e -> (e1, e))).SelectMany(e -> e); Здесь в последнем лямбда-выражении запроса GroupJoin мы преобразу- ем последовательность e2 (напомним, что в нее входят все элементы внут- ренней последовательности, имеющие одинаковый ключ с элементом e1) в последовательность пар (e1, e), где e пробегает все элементы последова- тельности e2, после чего превращаем набор преобразованных последова- 80 тельностей (т. е. иерархическую последовательность) в плоскую последо- вательность, используя запрос SelectMany(e -> e). Однако в результате мы получим обычное внутреннее объединение: Write(res); // [(10,40),(10,60),(21,51),(33,53)] Это вполне естественно, поскольку мы не предусмотрели обработку особой ситуации: когда с элементом e1 внешней последовательности нель- зя связать ни одного элемента внутренней последовательности и, таким образом, в последнем лямбда-выражении запроса GroupJoin последователь- ность e2 оказывается пустой. Как мы знаем, запрос SelectMany просто игно- рирует пустые последовательности. Для правильной обработки этой особой ситуации нам было бы доста- точно «превратить» пустую последовательность e2 в одноэлементную по- следовательность, содержащую то особое значение, которое в результиру- ющем плоском левом внешнем объединении мы хотим связать с «одино- кими» элементами внешней последовательности (в нашем случае таким одиноким элементом является число 84). В стандартной библиотеке платформы .NET предусмотрен запрос, De- faultIfEmpty специально предназначенный для решения подобных задач. Download 1.62 Mb. Do'stlaringiz bilan baham: |
Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©fayllar.org 2024
ma'muriyatiga murojaat qiling
ma'muriyatiga murojaat qiling