SORU
6 AĞUSTOS 2008, ÇARŞAMBA


'tuşları arasında dolaşmak için en güvenli yolu bir Perl karma?

Eğer (anahtar, değer) çiftleri bir sürü Perl bir karma varsa, tüm anahtarları yineleme tercih edilen yöntem nedir? each kullanarak bir şekilde istenmeyen yan etkileri olduğunu duydum. Bu doğru, iki aşağıdaki yöntemlerden biridir iyi, yoksa daha iyi bir yolu var mı?

# Method 1
while (my ($key, $value) = each(%hash)) {
    # Something
}

# Method 2
foreach my $key (keys(%hash)) {
    # Something
}

CEVAP
6 AĞUSTOS 2008, ÇARŞAMBA


Başparmak kuralı işlevi ihtiyaçlarınız için en uygun kullanmaktır.

Sen sadece anahtarları istiyorum ve hiç planlamıyorsanızokuyundeğerlerden birini kullanın keys():

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

Eğer sadece değerleri istiyorsanız, Kullanım Değerleri():

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

Eğer anahtarları ihtiyacınız varsavedeğerleri, kullanımı her():

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

Herhangi bir şekilde hash anahtarları değiştirmek için planlıyorsanızhariçyineleme sırasında mevcut anahtar silme için, her kullanmamalısınız(). Örneğin, iki katına çıktı değerleri ile büyük tuşları yeni bir dizi oluşturmak için bu kod iyi tuşlarını kullanarak çalışıyor():

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

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

beklenen sonuç üreten hash:

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

Ama her kullanarak() aynı şeyi yapmak için:

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

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

üretir öngörmek zor şekilde yanlış sonuçlar. Örneğin:

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

Bu, ancak, güvenli

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

Bu perl belgelerinde açıklanmıştır:

% perldoc -f keys
% perldoc -f each

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • case LianLi

    case LianLi

    28 Mayıs 2010
  • Tinkernut

    Tinkernut

    28 Aralık 2006
  • xSammyJoe1

    xSammyJoe1

    19 Temmuz 2011