Perl'de bir karma içeriğini nasıl yazdırabilirim?


167

Karma değerimi ayrılmış kova sayısı # olarak ayırmaya devam ediyorum. Karma içeriğimi nasıl yazdırabilirim?

Bir whiledöngü kullanılmadan en çok tercih edilir (örneğin, bir astar en iyi olurdu).

Yanıtlar:


253

Veri :: Damper senin arkadaşın.

use Data::Dumper;
my %hash = ('abc' => 123, 'def' => [4,5,6]);
print Dumper(\%hash);

çıktı olacak

$VAR1 = {
          'def' => [
                     4,
                     5,
                     6
                   ],
          'abc' => 123
        };

3
orijinal poster ayrıca çeşitli Data :: Dumper seçeneklerine de bakmak isteyebilir, özellikle 'Sortkeys'i açmak çok yararlı olabilir
plusplus

1
@JonathanDay Bu detayı kaçırıyordum ve yardımcı oldu! Teşekkürler!
Sos

5
% Önüne eğik çizgi eklemek ne anlama geliyor?
şampuan

16
@ shampoo slash operatörü, &C ve C ++ 'daki operatör gibi bir referans oluşturur . Bu bağlamda önemli olmasının nedeni, Perl'de, bağımsız değişken olarak karma değerine sahip bir işlev çağırırsanız, bu karma değerin listelenir ve birden çok bağımsız değişkene genişletilir - böylece %hsh=("a" => 1, "b" => 2); foo(%hsh);eşdeğer olur foo("a", 1, "b", 2). Bunun yerine işlevin karma üzerinde çalışmasını istiyorsanız, karma değerine bir referans iletmeniz gerekir : foo(\%hsh);Bkz. Perldoc.perl.org/perlsub.html#Pass-by-Reference
tetromino

63

Kolay:

print "$_ $h{$_}\n" for (keys %h);

Zarif, ama aslında% 30 daha yavaş (!):

while (my ($k,$v)=each %h){print "$k $v\n"}

9
Kalitesiz: "_ \ n" yazarken
_

Sanırım demek istiyorsun print "$_ $h{$_}\n" for (keys %h);, $kbu örnekte yok.
Chas. Owens

4
Ayrıca, verimlilikle ilgili iddialarda bulunmadan önce karşılaştırma (veya en azından bahsettiğiniz verimlilik türünü nitelendirme). forDöngü daha hızlı olduğu while: en az 10.000 tuşlara kadar gist.github.com/151792
Chas. Owens

1
Tabii haklısın: $ k. Ancak Perl 6'da daha verimli! :) Evet, sen de haklısın. Perl'imi gerçekten optimize etmeyi veya profil oluşturmayı asla düşünmezdim, ama bunu öğrenmekten memnunum. Tabii ki, her biri daha verimli olmalıdır (çünkü anahtarda fazladan karma arama yoktur). Ama ~% 30 daha yavaş!
Jonathan Graehl

Merhaba Jonathan Graehl. Üzgünüm, hala anlamıyorum. Her birinin neye göre ~% 30 daha yavaş olduğunu mu söylüyorsunuz? Her zaman, her durum için% 30'luk bir boşluk mu?
Carlos Sá


24

Hata ayıklama amacıyla sık sık kullanacağım YAML.

use strict;
use warnings;

use YAML;

my %variable = ('abc' => 123, 'def' => [4,5,6]);

print "# %variable\n", Dump \%variable;

Sonuçlar:

# %variable
---
abc: 123
def:
  - 4
  - 5
  - 6

Diğer zamanlarda kullanacağım Data::Dump. Sizden daha güzel bir biçimde çıktı alabilmesi için çok sayıda değişken ayarlamanıza gerek yoktur Data::Dumper.

use Data::Dump = 'dump';

print dump(\%variable), "\n";
{ abc => 123, def => [4, 5, 6] }

Son zamanlarda Data::Printerhata ayıklama için kullanıyorum .

use Data::Printer;
p %variable;
{
    abc   123,
    def   [
        [0] 4,
        [1] 5,
        [2] 6
    ]
}

(Sonuç bir terminalde çok daha renkli olabilir)

Burada gösterdiğim diğer örneklerin aksine, bu açıkça sadece görüntüleme amaçlı olacak şekilde tasarlanmıştır. Bağlı bir değişkenin veya bir nesnenin yapısını dökerseniz daha kolay görünür.

use strict;
use warnings;

use MTie::Hash;
use Data::Printer;

my $h = tie my %h, "Tie::StdHash";
@h{'a'..'d'}='A'..'D';
p %h;
print "\n";
p $h;
{
    a   "A",
    b   "B",
    c   "C",
    d   "D"
} (tied to Tie::StdHash)

Tie::StdHash  {
    public methods (9) : CLEAR, DELETE, EXISTS, FETCH, FIRSTKEY, NEXTKEY, SCALAR, STORE, TIEHASH
    private methods (0)
    internals: {
        a   "A",
        b   "B",
        c   "C",
        d   "D"
    }
}

renkleri "düzgün", ama ya yanlış bir şey yapıyorum ya da "use :: :: Yazıcı kullanın; p% var;" hashes okları yazdırmaz ve benim gibi yeni başlayan bir acemi için
Sos

@Sosi Cevaptaki çıktıya bakarsanız, =>beklediğiniz gibi çıkmadığını görürsünüz . Bunun yerine her zaman anahtarı, birkaç boşluğu ve sonra değeri yazdırır. Bu, bir çıktı üzerinde insan taramasına yardımcı olur.
Brad Gilbert

12

Bu sorunun cevabı, karma değerinizde ne olduğuna bağlıdır. Basit bir karma varsa

print map { "$_ $h{$_}\n" } keys %h;

veya

print "$_ $h{$_}\n" for keys %h;

ancak referanslarla doldurulmuş bir karmanız varsa, bu referansları yürütebilecek ve makul bir çıktı oluşturabilecek bir şey elde edersiniz. Referansların bu şekilde yürümesine normalde serileştirme denir. Farklı stilleri uygulayan birçok modül var, daha popüler olanlardan bazıları:

Aslında nedeniyle Data::Dumperçekirdek Perl kitaplığının parçasıdır, muhtemelen en popüler olduğu; ancak, bazı diğer modüllerin sunabileceği çok iyi şeyler var.


10

En sevdiğim: Smart :: Yorumlar

use Smart::Comments;
# ...

### %hash

Bu kadar.


5
Üzgünüm, gerçek işlevsellik için yorumları ele geçiren şeyler için benden aşağı oy verin. Bir bakım programcısı, tüm gün neden böyle bir kodun beklenmedik şeyler yazdırdığını çözmeye çalışarak harcayabilir.
MikeKulls

2
@MikeKulls, np. Bu bir kaynak filtresi, bu yüzden anlıyorum. Ayrıca, üretime hazırladığım her modülü kontrol etmeyen yazılı senaryolara sahip olmadığından use Smart::Comments, onu da bu perspektiften görüyorum. Ancak, karşı, Smart::Commentsoldukça kapsamlı bir modül gibi davranır , SC kullanmayan herhangi bir modülde çıkış davranışı olmamalıdır . Bu nedenle, sorun bir kullanım bildirimi ile bu kapsamlara ayrılacaktır . Bir bakım programcısının dahil edilen modüller hakkındaki dokümanı okuma sorumluluğu olmadığını söylüyorsanız, kabul edemem. Yine de, yorum yaptığınız için teşekkürler
Axeman

7
Sorumlulukları olmadığını söylemiyorum ama aradıkları ilk şey olması muhtemel değil. Yukarıdaki kod neden bir şey yazdırdığını bilmiyordum önce Akıllı Yorumlar modülünü hiç görmemiştim. Yorumun üzerinden atlayarak günler geçirebilirim ve hatta hiçbir şey yapmaması gerektiği için işlemezdim. Onları bir şey yapmak çok kötü imo. Programın davranışını değiştirmedikleri sürece dokümantasyon vb. Oluşturmak için kullanılabilirler.
MikeKulls

4

Döngü:

foreach(keys %my_hash) { print "$_ / $my_hash{$_}\n"; }

fonksiyonel

map {print "$_ / $my_hash{$_}\n"; } keys %my_hash;

Ama saf zerafet için, wrang-wrang'ları seçmeliydim. Kendi kodum için, foreach'mi seçerdim. Veya tetro'nun Dumper'ı kullanın.


3
Senin kullanımları arasında hiçbir işlevsel fark yoktur foreachve map. mapbir for-loop öykünmek için boşluk bağlamında değil, liste dönüşümleri için kullanılmalıdır
friedo

her birinin 'bayt kodu' sonuçlarını görmek ilginç olurdu ... Harita az ya da çok verimli olup olmadığını merak ediyorum.
Ape-inago

2

Deneyimlerimdeki en kolay yol sadece Dumpvalue kullanmaktır .

use Dumpvalue;
...
my %hash = { key => "value", foo => "bar" };
my $dumper = new DumpValue();
$dumper->dumpValue(\%hash);

Bir cazibe gibi çalışır ve Perl hata ayıklayıcısının yaptığı gibi çıktıyı biçimlendirmek için endişelenmenize gerek yoktur (hata ayıklama için harika). Ayrıca, Perl modüllerinin stok setinde Dumpvalue bulunur, bu nedenle bir çeşit acımasız proxy'nin arkasındaysanız (işteyim gibi) CPAN ile uğraşmak zorunda kalmazsınız.


1

Bilgiçlikçi olmak ve bir satırda tutmak istiyorsanız (kullanım ifadeleri ve shebang olmadan), o zaman bir tür domuzcuk tetromino cevabından geri döner ve öneririm:

print Dumper( { 'abc' => 123, 'def' => [4,5,6] } );

Temp değişkenini atlamak için anonim karma kullanmak dışında özel bir şey yapmamak;)


OP, baskıya ihtiyacı olan "hash'ım" olduğunu söylüyor. Bu cevap sadece kendi iyiliği için zekice
justintime

OP bunu tek bir satırda yapmayı umuyordu. Bunu yapmanın tek satırlık bir yolunu gösteriyordum. Yani bu aşağı oylamaya değer mi?
Kyle Walsh

1

İyi görmek için karma her elemanı için bir boşluk ekleyin:

print map {$_ . " "} %h, "\n";

1

Gerçekten bir liner kodu anahtarları sıralamak istiyorum:

print "$_ => $my_hash{$_}\n" for (sort keys %my_hash);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.