Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 [ 50 ] 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

5.10. Объединение хэшей 167

%merged = (%А, %В),

Для экономии памяти можно организовать перебор элементов и построить новый хэш следующим образом:

%merged = (),

while ( ($k,$v) = each(%A) ) {

$merged{$k} = $v,

while ( ($k,$v) = each(%B) ) {

$merged{$k} = $v,

Комментарий

в первом варианте, как и в предыдущем рецепте инвертирования хэшей, используется списковая эквивалентность, о которой говорилось во введении. (%А, %В) интерпретируется как список пар «ключ/значение». Когда он присваивается объединенному хэшу %merged, Perl преобразует список пар снова в хэш. Рассмотрим, как эта методика реализуется на практике:

# Хэш %food color определяется во Введении %drink color = ( Galliano => yellow ,

Mai Tai => blue ),

%ingested colors = (%drink color %food color),

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

Прямое присваивание компактно и наглядно, но при больших размерах хэшей оно приводит к большим расходам памяти. Это связано с тем, что перед выполнением присваивания итоговому хэшу Perl разворачивает оба хэша во временный список. Пошаговое объединение с помощью each, показанное ниже, избавит вас от этих затрат. Заодно вы сможете решить, как поступать с совпадающими ключами.

С применением each первый фрагмент записывается следующим образом:

# Хэш %food color определяется во Введении %drink color = ( Galliano => yellow ,

Mai Tai => blue ),

%substance color = (), while (($k, $v) = each %food color) { $substance color{$k} = $v

while (($k, $v) = each %drink color) { $substance color{$k} = $v,

Обратите внимание на повторяющийся код присваивания в циклах while. Проблема решается так:



foreach $substanceref (\%food color, \%drink color ) { while (($k, $v) = each %substanceref) { $substance color{$k} = $v,

Если в объединяемых хэшах присутствуют одинаковые ключи, можно вставить код для обработки дубликатов:

foreach $substanceref (\%food color, \%drink color ) { while (($k, $v) = each %substanceref) { if (exists $substance color{$k}) {

print Warning $k seen twice Using the first definition \n , next,

$substance color{$k} = $v,

В частном случае присоединения одного хэша к другому можно воспользоваться срезом для получения более элегантной заниси:

@all colors{keys %new colors} = values %new colors,

Потребуется память в объеме, достаточном для хранения списков всех ключей и значений %new colors. Как и в первом варианте, расходы памяти при большом размере списков могут сделать эту методику неприемлемой.

> Смотри также-

Описание функции each вperlfunc{\); рецепт 4.9.

5.11. Поиск общих или различающихся ключей в двух хэшах

Проблема

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

Решение

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

Поиск общих ключей

ту ©common = (), foreach (keys %hash1) {

push(@common, $ ) if exists $hash2{$ },

# ©common содержит общие ключи



5.12. Хэширование ссылок 169

Поиск ключей, отсутствующих в другом хэше

ту @this not that = (), foreach (keys %hash1) {

push(@this not that, $ ) unless exists $hash2{$ },

Комментарий

При поиске общих или различающихся ключей хэшей можно воспользоваться рецептами для поиска общих или различающихся элементов в массивах ключей хэшей. За подробностями обращайтесь к рецепту 4.8.

В следующем фрагменте поиск различающихся ключей применяется для нахождения продуктов, не входящих в хэш с описаниями цитрусовых;

# Хэш %food color определяется во введении

# %citrus color - хэш, связывающий названия цитрусовых плодов с их цветами %citrus color = (Lemon => yellow ,

Orange => orange , Lime => green ),

n Построить список продуктов не входящих в хэш цитрусовых @non-citrus = 0,

foreach (keys %food color) {

push (@non citrus, $ ) unless exists $citrus color{$ },

> Смотри также-

Описание фущсции each врег1/тс(1). Срезы хэшей рассматриваются Bperldata(l).

5.12. Хэширование ссылок

Проблема

Если функция keys вызывается для хэша, ключи которого представляют собой ссылки, то возвращаемые ей ссылки не работают. Подобная ситуация часто возникает при создании перекрестных ссылок в двух хэшах.

Решение

Воспользуйтесь модулем Tie::Refflash:

use Tie RefHash,

tie %hash, Tie RefHas ,

n Теперь в качестве ключей хэша %hash можно использовать ссылки

Комментарий

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



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 [ 50 ] 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242