Анимация
JavaScript
|
Главная Библионтека 4.6. Выборка уникальных элементов из списка 125 Однако ссылка на массив нередко является результатом более сложного выражения. Для превращения такого результата в массив применяется конструкция @{ EXPR }: $namelist{felines} = \@годие саТз, foreach Scat ( @{ Snamelist{felines} } ) { print Scat purrs hypnotically \n , print --More--\nYou are controlled \n Как и прежде, цикл foreach можно заменть эквивалентны.м циклом for: for ($1=0, $1 <= $#{ Snamelistifelines) ), $i++) { print $namolist{felines}[$i] purrs hypnotically \n , > Смотри также- peiiref{\) и peillo!(i); рецепты 4 4; 11.1. 4.6. Выборка уникальных элементов из списка Проблема Требуется удалить из списка повюряюпщеся элементы - например, при построении списка пз файла или па базе выходшлх данных некоей команды. Рецепт в paBHoii мерс относится как кудален1по дуб.11икатов при вводе, так и в уже заполненных Maccinsax. Решение Хэш нсполь,)уется для сохранения встречавшихся ранее элементов, а фуик-ция keys - для их извлечения. Пршштая в Perl концепция пстппности позволит уменьшить объем программы и ускорить ее работу. Прямолинейно %seen = 0, i?uniq = () foreach $itpm ((Silist) { unless ($seen{$item}) # Если мы попали сюда, значит, элемент не встречался ранее $seen{Sitem} = 1 push(@uniq Sitem), Быстро %seen =0, foreach Sitem ((aiist) { push((suniq Sitem) unless Sseen{$item}++, Аналогично, но с пользовательской функцией %seen = 0, foreach Sitem ((alist) { so(tie func($ite(ti) unless $seen{$ite(ti}++ Быстро, HO по-другому %seen = 0, foreach litem ((alist) { $seen{$iteni}++, (auniq = keys %seen, Быстро и совсем по-другому %seen = 0, (aunique = grep { $seen{$ } ++ } (alist, Комментарий Суть сводится к простому вопросу - встречался ли данный элемент раньше? Кэши идеально подходят для подобного поиска. В нервом варианте («Прямо;нт-нейно») массив уникальных зпачеппй строится но мере обработки исходного списка, а для регистрации встречавшихся значений используется хэш. Второй вариант («Быстро») представляет собот"! самый естествепньй! способ решения подобных задач в Perl. Каждый раз, К01да встречается новое значение, в хэш с помощью оператора ++ добавляется новый элемент. ПобочпыГ! эффект состоит в том, что в хэш попадают ы е повторяющиеся экземпляры. В данном случае хэш работает как множество. Третий вариант («Аналогично, но с пользовательской функцией») похож на второй, однако вместо сохранения значения мы вызываем некоторую пользовательскую функцию и передаем ей это значение в качестве аргумента. Если ничего больше не требуется, хранить отдельны!! массив уникальных з!1ачепий будет т!з-лишне. В следующем варианте («Быстро, i!o по-другому») уникальные ключи извле-!саются из хэпга %seen лишь после toi-o, как оп будет полностью построен. Иногда это удоб!!о, но исход1!ый порядок элсментов утрачивается. В послед1!ем вариа!!те («Bi)icTpo и совсем но-друголту») построение хэша %seen объед11!!яется с нзвлече1!ием уп1!калы!ых элементов. При этом сохраняется исход-!1ый порядок элементов. Использование хэша для записи зпаче1!НЙ имеет два побочных эффекта: npi! обработке длип!!Ь!х сшгсков расходуется N!i!oro памяти, а сп!1сок, возвращаем!)1Й keys, !ie отсортирова!! в алфав!1тном или числовом порядке и !!е сохра1!яет порядок вставки. 4.7. Поиск элементов одного массива, отсутствующих в другом массиве 127 Ниже показано, как обрабатывать да1И1ые по мере ввода. Мы используем who для получения сведений о текущем сниске пользователей, а перед обновлением хэща извлекаем из каждой строки имя пользователя: # Построить список зарегистрированных пользователей с удалением дубликатов %ucnt = 0, for ( who ) { s/\s *\n , # Стереть от первого пробела до конца строки - # остается имя пользователя $ucnt{$ }++, # Зафиксировать присутствие данного пользователя # Извлечь и вывести уникальные ключи (ausers = sort keys %ucnt, print users logged in @users\n , > Смотри также- Раздел «Foreach Loops» ре/%и(1); описание функции keys в реИ/ипс{\). Апа7ю-гичное примеиепие хэшей продемонстрировано в рецептах 4.7 и 4.8. 4.7. Поиск элементов одного массива, отсутствующих в другом массиве Проблема Требуется найти элементы, которые присутствуют в одном массиве, но отсутствуют в другом. Решение Мы ищем элементы @А, которых нет в @В. Постройте хэш из ключей @В - он будет использоваться в качестве таблицы просмотра. Затем проверьте каждый элемент @А и посмотрите, присутствует ли он в @В. Простейшая реализация # Предполагается, что @А и @В уже загружены %seen =0, # Хэш для проверки принадлежности элемента В (aaonly =0, # Ответ # Построить таблицу просмотра foreach $item (©В) { $seen{$iteni} = 1 } # Найти элементы @А, отсутствующие в @В foreach $item (©А) { unless Sitem ((ЭА) { # Отсутствует в %seen, поэтому добавить в ©aonly push(@aonly, Sitem), 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 |