Итерация "модификатора оператора" по хешу?

Я обнаружил, что хочу использовать формы оператора-модификатора итерации по хешам в Perl (v5):

my %h = (...);
do_something($_[0], $_[1]) for each %h;  ### $_[0] => key, $_[1] => val

Или:

my %h = (...);
my @ary = %h;
do_something($_[0], $_[1]) for splice(@ary, 0, 2);

Конечно, ни одна из этих форм не существует. Просто любопытно, проводилась ли какая-либо работа по поддержке использования splice или each с формой модификатора операторов for? В Perl 6 или через backport v5?

each даже не шлейф.
melpomene 09.09.2018 10:26

@melpomene Хорошее замечание, я обновил сообщение, чтобы поставить each на одну ногу с splice

textral 09.09.2018 12:51
for each %h уже делает что-то еще: each возвращает список из двух элементов (ключ, значение), а for выполняет итерацию по нему.
melpomene 09.09.2018 12:52

Под «модификатором оператора» вы имеете в виду функцию do_something(...), которая изменяет значения $_[0] и $_[1]?

mob 09.09.2018 18:05

@mob: Под «модификатором оператора» я подразумеваю синтаксис Perl, описанный здесь: perldoc.perl.org/perlsyn.html#Statement-Modifiers

textral 10.09.2018 01:20
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
116
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

В List :: Util и List :: MoreUtils есть несколько отличных функций, которые могут помочь в подобных ситуациях. В частности, обратите внимание на pairs:

use List::Util qw{pairs};

do_something($_->[0], $_->[1]) foreach pairs %h;

Или, если вы можете переварить карту в пустом контексте:

use List::Util qw{pairmap};

pairmap { do_something($a, $b) } %h;

Ах, List :: Util, я должен был знать :) Я также придумал следующее, что тоже работает: do_something($_->[0], $_->[1]) for map { CORE::state @bob; push @bob, $_; @bob % 2 ? () : do {my @tmp = @bob; @bob = (); \@tmp} } %h (Может, List :: Utils :: pair делает что-то похожее за кулисами?) Я просто хочу посмотреть, что другие придумать, поэтому я оставлю его открытым в другой день. В противном случае ваш ответ кажется приемлемым.

textral 09.09.2018 13:29

@textral, do {my @tmp = @bob; @bob = (); \@tmp} - это длинный способ записи [splice(@bob)]. И ваше решение терпит неудачу (т.е. плохо), если предоставлено нечетное количество аргументов.

ikegami 09.09.2018 21:26

Самое чистое решение - следующее:

do_something($_, $h{$_}) for keys %h;

Если вы хотите сэкономить память, вы можете использовать each как обычно.

{ my ($k, $v);  do_something($k, $v) while ($k, $v) = each(%h); }

Конечно, это намного чище без использования модификатора оператора.

while (my ($k, $v) = each(%h)) { do_something($k, $v); }

Наконец, если вы на самом деле не имеете дело с хешем, можно использовать pairs из List :: Util.

use List::Util qw( pairs );

do_something(@$_) for pairs %h;

Этот последний подход очень расточителен, поскольку неэффективно создает множество массивов.

Да, верно: я использовал вашу первую форму раньше ... не знаю, почему я не подумал об этом на этот раз. И хотя это, вероятно, лучший способ, я думаю, что должен принять ответ @mwp, потому что мой исходный вопрос (хотя я сформулировал его плохо) был больше о том, как потреблять более одного элемента за раз из списка с использованием модификаторов оператора цикла . Я понимаю, что технически Perl (в настоящее время?) Не допускает этого, но, по крайней мере, List::Util::pairs производит «впечатление» именно этого (и @mwp первым опубликовал информацию о List::Util::pairs).

textral 11.09.2018 02:59

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

ikegami 11.09.2018 05:47

И я не уверен, почему вы говорите, что использование pairs - это решение mwp; Я также предложил это, и я даже предложил более простой способ его использования.

ikegami 11.09.2018 05:49

@mwp отправил pairs в качестве ответа за 8 часов до вас. Но да, ваше расширение @$_ ссылки на массив, возвращаемое pairs, проще для глаз, чем использование mwp

textral 11.09.2018 09:14

Что касается "отправил пары в качестве ответа за 8 часов до того, как вы это сделали.", я знал об этом. Я просто указал, что дважды вы писали, что принимаете ответ mwp, потому что они использовали pairs, что не имеет смысла.

ikegami 11.09.2018 09:16

небольшое улучшение вашего решения while: do_something(@_) while @_ = each %h

textral 11.09.2018 15:30

Это очень опасно, и этого следует избегать

ikegami 11.09.2018 21:31

Хорошо, хотя установка элементов @_ опасна, установка @_ в целом таким образом - нет. Тем не менее, возиться с глобальными переменными - особенно с такой особенной - нельзя.

ikegami 12.09.2018 08:31

это безопаснее? do_something(@_) while local @_ = each %h

textral 16.09.2018 15:20

local здесь ничего не делает, потому что нет никаких завитушек, которые его ограничивали.

ikegami 16.09.2018 16:13

извините, что откопал старый пост, но с тех пор я тестировал do_something(@_) while local @_ = each %h, и он работает: все, что назначено для @_ до запуска команды, остается в @_ после запуска команды

textral 30.04.2020 16:33

@textral, хорошо, но он все еще не читается (неинтуитивно, неожиданное поведение), и он по-прежнему использует each, который плохо справляется с проблемами.

ikegami 30.04.2020 16:39

Вы можете сократить

{my ($k, $v);  do_something($k, $v) while ($k, $v) = each(%h); }

к

do_something($a, $b) while ($a, $b) = each %h;

поскольку $ a и $ b уже объявлены для сортировки.

Другие вопросы по теме