Чего самый безопасный путь состоит в том, чтобы выполнить итерации через ключи хеша Perl?

Ниже приведен пример передачи параметров в документ fxml через пространство имен.

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<VBox xmlns="http://javafx.com/javafx/null" xmlns:fx="http://javafx.com/fxml/1">
    <BorderPane>
        <center>
            <Label text="$labelText"/>
        </center>
    </BorderPane>
</VBox>

Определить значение External Text для переменной пространства имен labelText:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class NamespaceParameterExampleApplication extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws IOException {
        final FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("namespace-parameter-example.fxml"));

        fxmlLoader.getNamespace()
                  .put("labelText", "External Text");

        final Parent root = fxmlLoader.load();

        primaryStage.setTitle("Namespace Parameter Example");
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }
}
101
задан brian d foy 3 December 2008 в 04:11
поделиться

8 ответов

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

, Если Вы просто хотите ключи и не планируете к никогда , читает любое из значений, используют ключи ():

foreach my $key (keys %hash) { ... }

, Если Вы просто хотите значения, используйте значения ():

foreach my $val (values %hash) { ... }

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

keys %hash; # reset the internal iterator so a prior each() doesn't affect the loop
while(my($k, $v) = each %hash) { ... }

, Если Вы планируете изменить ключи хеша всегда кроме [1 111] для удаления текущего ключа во время повторения, тогда Вы не должны использовать каждого (). Например, этот код для создания нового набора прописных ключей с удвоенными значениями хорошо работает с помощью ключей ():

%h = (a => 1, b => 2);

foreach my $k (keys %h)
{
  $h{uc $k} = $h{$k} * 2;
}

создание ожидаемого получающегося хеша:

(a => 1, A => 2, b => 2, B => 4)

, Но использующий каждого (), чтобы сделать то же самое:

%h = (a => 1, b => 2);

keys %h;
while(my($k, $v) = each %h)
{
  $h{uc $k} = $h{$k} * 2; # BAD IDEA!
}

приводит к неправильным результатам твердо предсказываемыми способами. Например:

(a => 1, A => 2, b => 2, B => 8)

Это, однако, безопасно:

keys %h;
while(my($k, $v) = each %h)
{
  if(...)
  {
    delete $h{$k}; # This is safe
  }
}

Все это описано в документации жемчуга:

% perldoc -f keys
% perldoc -f each
192
ответ дан ysth 5 November 2019 в 11:40
поделиться

Одна вещь, о которой необходимо знать при использовании each , состоит в том, что это имеет побочный эффект добавляющего "состояния" к хешу (хеш должен помнить то, что "следующий" ключ). Когда использование кода как отрывки отправило выше, которые выполняют итерации по целому хешу сразу, это обычно - не проблема. Однако Вы столкнетесь трудно для разыскивания проблем (я говорю на основе опыта;), при использовании each вместе с операторами как last или return для выхода от while ... each цикл перед обработкой всех ключей.

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

Пример:

my %hash = ( foo => 1, bar => 2, baz => 3, quux => 4 );

# find key 'baz'
while ( my ($k, $v) = each %hash ) {
    print "found key $k\n";
    last if $k eq 'baz'; # found it!
}

# later ...

print "the hash contains:\n";

# iterate over all keys:
while ( my ($k, $v) = each %hash ) {
    print "$k => $v\n";
}

Это печатает:

found key bar
found key baz
the hash contains:
quux => 4
foo => 1

, Что произошло с ключами "панель" и baz"? Они все еще там, но второе each запускается, где первый, брошенный, и, останавливается, когда он достигает конца хеша, таким образом, мы никогда не видим их во втором цикле.

25
ответ дан 8jean 5 November 2019 в 11:40
поделиться

Место, где each может вызвать Вас проблемы, - то, что это - истинный, неограниченный по объему итератор. Как пример:

while ( my ($key,$val) = each %a_hash ) {
    print "$key => $val\n";
    last if $val; #exits loop when $val is true
}

# but "each" hasn't reset!!
while ( my ($key,$val) = each %a_hash ) {
    # continues where the last loop left off
    print "$key => $val\n";
}

, Если необходимо быть уверены, что each получает все ключи и значения, необходимо удостовериться, что Вы используете keys или values первый (поскольку это сбрасывает итератор). Посмотрите документация для каждого .

20
ответ дан Darren Meyer 5 November 2019 в 11:40
поделиться

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

Так, единственное место, "каждый" имеет реальное применение, - когда хеш является очень большим (по сравнению с доступной памятью). Это, только, вероятно, произойдет, когда сам хеш не будет жить в самой памяти, если Вы не программируете карманное устройство сбора данных или что-то с маленькой памятью.

, Если память не является проблемой, обычно парадигма карты или ключей является большим количеством prevelant и легче считать парадигму.

13
ответ дан 5 November 2019 в 11:40
поделиться

Несколько разных мыслей об этой теме:

  1. нет ничего небезопасного ни об одном из самих итераторов хеша. То, что небезопасно, изменяет ключи хеша, в то время как Вы выполняете итерации по нему. (Совершенно безопасно изменить значения.) Единственный потенциальный побочный эффект, о котором я могу думать, состоит в том, что values псевдонимы возвратов, что означает, что изменение их изменит содержание хеша. Это дизайном, но не может быть тем, что Вы хотите при некоторых обстоятельствах.
  2. John's принятый ответ хорош за одним исключением: документация является четкой, которого не безопасно добавить ключи при итерации по хешу. Это может работать на некоторые наборы данных, но перестанет работать для других в зависимости от порядка хеша.
  3. , Как уже отмечено, безопасно удалить последний ключ, возвращенный each. Это не верно для keys, как each итератор в то время как keys возвраты список.
6
ответ дан Community 5 November 2019 в 11:40
поделиться

Я всегда использую метод 2 также. Единственное преимущество использования каждого - то, если Вы просто читаете (вместо того, чтобы повторно присвоиться) значение записи хеша, Вы постоянно не разыменовываете хеш.

3
ответ дан jaredg 5 November 2019 в 11:40
поделиться

Я могу быть укушен этим, но я думаю, что это - персональное предпочтение. Я не могу найти ссылку в документах каждому () быть отличающимся, чем ключи () или значения () (кроме очевидного, "они дают разные вещи" ответ. На самом деле документы указывают использованию тот же итератор, и они все возвращают фактические значения списка вместо копий их, и что изменение хеша при итерации по нему с помощью любого вызова плохо.

Однако я почти всегда использую ключи (), потому что мне это обычно - больше сам документирующий для доступа к значению ключа через сам хеш. Я иногда использую значения (), когда значение является ссылкой на большую структуру, и ключ к хешу был уже сохранен в структуре, в которой точке ключ избыточен, и мне не нужен он. Я думаю, что использовал каждого () 2 раза за 10 лет программирования Perl, и это был, вероятно, неправильный выбор оба раза =)

3
ответ дан brian d foy 5 November 2019 в 11:40
поделиться

Я обычно использую keys и я не могу думать в прошлый раз, когда я использовал, или считайте использование each.

Не забывайте о map, В зависимости от того, что Вы делаете в цикле!

map { print "$_ => $hash{$_}\n" } keys %hash;
2
ответ дан Gary Richardson 24 November 2019 в 04:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: