Анимация
JavaScript
|
Главная Библионтека Ho тогда почему бы не воспользоваться хэшем? объект должен выглядеть как настоящий массив с префиксом @, а не как скалярная величина, содержащая ссылку на массив. В противном случае придется добавлять префикс вручную, что сделает функцию менее наглядной: $line[5] = \(S)list, @got = рор2( @{ $line[5] } ), Перед вами еще один пример, когда вместо простого списка должен использоваться массив. Прототип \@ требует, чтобы объект, занимающий данную позицию в списке аргументов, был массивом. $line[5] представляет собой не массив, а ссылку на него. Вот почему нам понадобился «лищний» знак @. > Смотри также - Описание функции splice вperlfunc(iy, раздел «Prototypes» perlsub(\). Функция splice используется в рецепте 4.9. 4.12. Поиск первого элемента списка, удовлетворяющего некоторому критерию Проблема Требуется найти первый элемент списка, удовлетворяющего некоторому критерию (или индекс этого элемента). Возможна и другая формулировка - определить, проходит ли проверку хотя бы один элемент. Критерий может быть как простым («Присутствует ли элемент в списке?»), так и сложным («Имеется список работников, отсортированный в порядке убывания оклада. У кого из менеджеров самый высокий оклад?»). В простых случаях дело обычно ограничивается значением элемента, но если сам массив может изменяться, вероятно, следует определять индекс первого подходящего элемента. Решение Перебирайте элементы в цикле foreach и вызовите last, как только критерий будет выполнен: ray($raatch, Sfound Sitern), foreach $11ега(@аггау) { if ($criterion) { Sraatch = $item, # Необходимо сохранить Sfound = 1 last, if($found) { ## Сделать что-то с Smatch } else { 4.12. Поиск первого элемента списка, удовлетворяющего некоторому критерию 135 ## Неудачный поиск Чтобы определить индекс, перебирайте все индексы массива и вызывайте last, как только критерий выполнится: (tiy($i, $(tiatch idx), for ($1 =0, $1 < ©array $i++) { If ($criterion) { $(tiatch idx = $1, # Сохранить индекс last, if(defined $raatch idx) { ## Найден элемент $array[$match idx] } else { ## Неудачный поиск Комментарий Стандартных механизмов для решения этой задачи не существует, поэтому мы напишем собственный код для перебора и проверки каждого элемента. В нем используются циклы foreach и for, а вызов last прекращает проверку при выполнении условия. Но перед тем, как прерывать поиск с помощью last, следует сохранить найденный индекс. Одна из распространенных ошибок - использование функции grep. Дело в том, что grep проверяет все элементы и находит все совпадения; если вас интересует только первое совпадение, этот вариант неэффективен. Если нас интересует значение первого найденного элемента, присвойте его переменной $match. Мы не можем просто проверять $item в конце цикла, потому что foreach автоматически локализует иеременпую-итератор и потому не позволяет узнать ее последнее значение после завершения цикла (см. рецепт 4.4) Рассмотрим пример. Предположим, в массиве ©employees находится список объектов с информацией о работниках, отсортированный в порядке убывания оклада. Мы хотим найти инженера с максимальным окладом; это будет первый инженер в массиве. Требуется только вывести имя инженера, поэтому нас интересует не индекс, а значение элемента. foreach $ешр1оуее (©employees) { if ( $eraployee->category() eq engineer ) { $highest engineer = $employee last, print Highest paid engineer is , $highest engineer->name(), \n , Термин «локализация» по отношению к переменной означает придание ей локальной области действия - Примеч перев Если пас интересует лишь значение индекса, можно сократить программу - достаточно вспомнить, что при неудачном поиске $1 будет содержать недопустимый индекс. В основном экономится объем кода, а не время выполнения, поскольку затраты на присваивание невелики по сравнению с затратами на проверку элементов списка. Однако проверка условия if ($i < @ARRAY) выглядит несколько туманно по сравнению с очевидной проверкой defined из приведенного выше решения. for ($1 =0, $1 < @ARRAY, $1++) { last if $criterion, If ($1 < @ARRAY) { ## Критерий выполняется по индексу $i } else { ## Неудачный поиск [> Смотри также- Разделы «Рог Loops», «РогеасЬ Loops» и «Еоор Control*perlsyn{\)\ описание функции grep вperlfunc{\). 4.13. Поиск всех элементов массива, удовлетворяющих определенному критерию Проблема Требуется найти все элементы анюка, удовлетворяющие определетюму критерию. Проблема извлечения подмножества из списка остается прежней. Вопрос заключается в том, как найти всех инженеров в списке работников, всех пользователей в административной группе, все 1Н1тересующие вас имена файлов и т. д. Решение Воспользуйтесь функцией grep. Функция применяет критерий ко всем элементам списка и возвращает лишь те, для которых он выполняется: ©РЕЗУЛЬТАТ = grep { КРИТЕРИЙ ($ ) ) ©СПИСОК, Комментарий То же самое можно было сделать в цикле foreach: ©РЕЗУЛЬТАТ =0, foreach (©СПИСОК) { 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 |