Portál AbcLinuxu, 20. dubna 2024 00:02


Dotaz: Perl - vypsat nazvy polozek v seznamu?

Slick avatar 4.7.2006 10:42 Slick | skóre: 4
Perl - vypsat nazvy polozek v seznamu?
Přečteno: 241×
Odpovědět | Admin
Zdravim vsechny!
Mel bych takovy zacatecnicky dotaz.

potreboval bych vypsat nazvy scalaru v seznamu

foreach( @seznam ) {
print $_ . "\n" ;
}

... mi sice vypise obsah jednotlivych promennych
ale ja bych potreboval vypsat i jejich nazvy.


Neexistuje nejakej $-něco- co to umoznuje?

Predem diky
As Barbie says: "Unix is complicated."
Nástroje: Začni sledovat (2) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

4.7.2006 10:49 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v seznamu?
Odpovědět | | Sbalit | Link | Blokovat | Admin
Nerozumím otázce. Co je to prosím nazvy scalaru v seznamu? Nejlépe, kdyby jste vypsal co přesně máte v @seznam a jak má vypadat výsledek.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
Slick avatar 4.7.2006 11:03 Slick | skóre: 4
Rozbalit Rozbalit vše Perl - vypsat nazvy polozek v array
Ok mozna jsem mel misto seznam napsat spis array... jsem llama

my $radek = <>;
my @array = ( my $jmeno, my $prijmeni, my $telefon) = split ' ', $radek;

foreach(@array) {
print $_ . "\n";
}

Tohle mi pekne vypise to co tomu dam, ale ja bych jeste potreboval aby to vypsalo nazvy jednotlivych prvku v ty array, jako je $jmeno, $prijmeni, atd..a to tak aby finalni vypis vypadal nejlepe :
$jmeno = Jan
$prijmeni = Novak
$telefon = 606123456
As Barbie says: "Unix is complicated."
4.7.2006 11:10 Petr Jelínek | skóre: 17 | blog: Vyprovokovanej | Praha
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Už to tu psal myšák - použij hash. Viz manuálové stránky, je tam toho mraky...
Nemám rád NVidii!
Slick avatar 4.7.2006 11:12 Slick | skóre: 4
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Hmm takze pres array teda cesta nevede ...
Diky.
As Barbie says: "Unix is complicated."
4.7.2006 11:11 miso | skóre: 36 | blog: iSCSI_initiator_howto | Praha
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
To je cele zle!
To co chces ziskat sa v datovom type array neuklada!
Pouzivaj hash - vid google
Project Satan infects Calculon with Werecar virus
Slick avatar 4.7.2006 11:14 Slick | skóre: 4
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
OK OK diky
Slick a.k.a. Perl-llama
As Barbie says: "Unix is complicated."
4.7.2006 11:18 miso | skóre: 36 | blog: iSCSI_initiator_howto | Praha
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Skus pouzit Dumper() - ako v tom mojom priklade dole.
To Ti urcite pomoze pochopit tieto veci
Project Satan infects Calculon with Werecar virus
4.7.2006 11:34 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Možností je milión a jedna. Například:
my $radek = <>;
my %thinks;
@thinks{qw(jmeno prijmeni telefon)} = split ' ', $radek;

while (my ($name, $value) = each %thinks) {
  print "$name = $value\n";
}
Ale to jsem ti asi moc nepomohl, protože to není setřízené. A nebo takhle?
my $radek = <>;
my @names = qw(jmeno prijmeni telefon);
my %thinks;
@thinks{@names} = split ' ', $radek;
foreach my $name (@names) {
  print "$name = $thinks{$name}\n";
}
Nebo takhle:
my $radek = <>;
my @names = qw(jmeno prijmeni telefon);
my $i = 0;
no strict 'refs';
${$names[$i++]} = $_ foreach (split ' ', $radek)[0..$#names];
foreach (@names) {
  print "$_ = ${$_}\n";
}
To už bylo trochu silnější kafe, že :-) To už by bylo lepší
my $radek = <>;
my @names = qw(jmeno prijmeni telefon);
my @array = split ' ', $radek;
for(my $i=0; $i<@names; $i++){
  print "$names[$i] = $array[$i]\n";
}
Já osobně bych použil tohle nebo tu druhou možnost.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
Slick avatar 4.7.2006 12:03 Slick | skóre: 4
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Dekuji O pane,
ta posledni varianta se mi moc libi,
to je presne to co jsem potreboval :-D.

Diky moc
As Barbie says: "Unix is complicated."
4.7.2006 12:14 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
a jeden pre vsetky riadky vstupu :-)
sub {
    map { print shift, ': ', $_, "\n"; } split ':', scalar <> || exit
}->(qw(meno prijmeni telefon)) while 1;
4.7.2006 13:04 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Tak tenhle přístup mě nenapadl. Moc hezké, já bych jen ještě ošetřil počet výstupů ze split
sub {
    map print(shift, ": $_\n"), (split / /, scalar <>)[0..$#_] or exit
}->(qw(meno prijmeni telefon)) while 1;
nebo
sub {
    map print(shift, ": $_\n"), split / /, scalar <>, @_ or exit
}->(qw(meno prijmeni telefon)) while 1;
Podle toho jak se to má chovat.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
4.7.2006 12:52 myšák | skóre: 26 | blog: EmentuX | Ostrava
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array

Já jsem teda, (nejen) co se týče PERLu, lama :-), ale můžu se zeptat jakou má výhodu použít místo hashe dvě pole? Berte to jako čistě technický dotaz bez jakýchkoliv narážek - jen mě zajímá, jestli je to paměťově méně náročné nebo výkonnější řešení než použít jeden hash... Děkuji.

Je nesmírně těžké být idiotem, konkurence je obrovská...
Slick avatar 4.7.2006 13:10 Slick | skóre: 4
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Hele ja jsem taky llama a protoze tohle je jednuduchy,
tak jsem pochopil jak to funguje ;-)
k HASHum jsem se jeste nedostal... :-D
As Barbie says: "Unix is complicated."
4.7.2006 13:24 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Zalezi na situacii a planovanom pouziti, moze sa stat, ze hash bude zaberat menej pamate ako dve polia, ale moze to byt i naopak. To iste plati pre vykonove porovnanie.
4.7.2006 13:32 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Je to rychlejší a méně paměťově náročné. Teda v tomhle případě ne, ale pokud by těch @array bylo opravdu hodně a @names mi stačí jen jednou, kdežto v hashi se mi se mi keys ukládají pořád znova a znova. Ten rozdíl je v tomhle
my @names = qw(jmeno prijmeni telefon)
my @arrays = ([qw(Franta Novák 564321564)]) x 1000000;
versus
my @seznam = ({jmeno => 'Franta', prijmeni => 'Novák', telefon => 564321564})  x 1000000;
To druhé zabere poněkud víc paměti a přístup k jednotlivým položkám je o chloupek pomalejší i když se s tím zase líp pracuje. Jedním ze spůsobů jak to udělat elegantně s polem je třeba
my $counter;
BEGIN {
  my $index = $counter++;
  sub jmeno() {$index}
}
BEGIN {
  my $index = $counter++;
  sub prijmeni() {$index}
}
BEGIN {
  my $index = $counter++;
  sub telefon() {$index}
}

my @seznam;
while (<>) {
  chomp;
  push @seznam, [(split ' ')[0 .. $counter-1]];
}

foreach (@seznam) {
  my @record = @$_;
  print <<EOF;
jmeno: $record[jmeno]
prijmeni: $record[prijmeni]
telefon: $record[telefon]

EOF
}
Jen podotýkám, že funkce s prototypem jmeno, prijmeni a telefon jsou de facto konstanty a vloží se inline. Dělám to samé co modul const.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
4.7.2006 13:41 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
pokial ma pamat neklame (moja, nie RAM), tak perl indexuje vsetky hodnotu raz pouzite ako kluc v hash-i, takze napr retazec "prijmeni" je pre vsetky hashe ulozeny iba raz a ako kluc sa pouziva jeho index.

dalsie elegantne riesenie (skoro zhodne s tymi konstantami):

package aaa;

use fields qw(jmeno prijmeni telefon)

package main;

my aaa $array = [ 0, split / /, $radek ];
print "jmeno: $array->{jmeno}\n";
4.7.2006 14:01 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
pokial ma pamat neklame (moja, nie RAM), tak perl indexuje vsetky hodnotu raz pouzite ako kluc v hash-i, takze napr retazec "prijmeni" je pre vsetky hashe ulozeny iba raz a ako kluc sa pouziva jeho index.
$ perl -e '@seznam = ({jmeno => 'Franta', prijmeni => 'Novak', telefon => 564321564}) x 10000000; sleep 10'&
$ ps -o pid,rss,vsz,cmd -Cperl
  PID   RSS    VSZ CMD
27137 236440 267004 perl -e @seznam = ({jmeno => Franta, prijmeni => Novak, telefon => 564321564}) x 10000000; sleep 10
$ perl -e 'my @names = qw(jmeno prijmeni telefon);my @arrays = ([qw(Franta Novák 564321564)]) x 10000000; sleep 10'&
$ ps -o pid,rss,vsz,cmd -Cperl
  PID   RSS    VSZ CMD
27143 236456 267004 perl -e my @names = qw(jmeno prijmeni telefon);my @arrays = ([qw(Franta Novák 564321564)]) x 10000000; sleep 10
Zdá se, že máte pravdu, takže zůstavá už jen ten ždibíček rychlosti.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
4.7.2006 14:22 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Aaaaaa, já jsem trouba :-( Vždyť jsem vytvářel milion odkazů na tentýž hash a totéž pole a to je samozřejmě stejné. Takže perl to vážně nedělá, ale pokaždé uloží nové klíče:
$ perl -e '@names = qw(jmeno prijmeni telefon);for($i=0;$i<1000000;$i++){push @arrays, [qw(Franta Novák 564321564)]};print "done\n"; sleep 10'&
done
$ ps -o pid,rss,vsz,cmd -Cperl
  PID   RSS    VSZ CMD
27376 209568 213616 perl -e @names = qw(jmeno prijmeni telefon);for($i=0;$i<1000000;$i++){push @arrays, [qw(Franta Novák 564321564)]};print
$ perl -e 'for($i=0;$i<1000000;$i++){push @arrays, {jmeno => Franta, prijmeni => Novak, telefon => 564321564}};print "done\n"; sleep 10'&
done
$ ps -o pid,rss,vsz,cmd -Cperl
  PID   RSS    VSZ CMD
27512 248860 252932 perl -e for($i=0;$i<1000000;$i++){push @arrays, {jmeno => Franta, prijmeni => Novak, telefon => 564321564}};print "done
$ perl -e 'sleep 10'&
$ ps -o pid,rss,vsz,cmd -Cperl
  PID   RSS    VSZ CMD
27554  1240   5320 perl -e sleep 10
Ten rozdíl je po odečtení režije perlu skoro celá pětina. A to jsou ty klíče relativně krátké.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
4.7.2006 14:41 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Nieco na tom asi bude, hlavne ziaden rozdiel medzi tretim a stvrtym pokusom je zarazajuci. Je jasne, ze asociativne pole zozerie viac pamate, ale nebude to ukladanim klucov, ale len jeho implementaciou.
  PID   RSS    VSZ CMD
 5873 315240 317176 perl -e '@list = map { {$_ => $_ } } 0 .. 1000000; print "done\n"; sleep 10'
 5880 393688 395572 perl -e '@list = map { {$_ => $_, $_+1 => $_, $_+2 => $_} } 0 .. 1000000; print "done\n"
 5888 268208 270132 perl -e '@list = map { {1 => $_, 2 => $_, 3 => $_} } 0 .. 1000000; print "done\n"; sleep 10'
 5894 268208 270132 perl -e '@list = map { {10001 => $_, 10002 => $_, 10003 => $_} } 0 .. 1000000; print "done\n"; sleep 10'
 5898 205440 207300 perl -e '@list = map { [$_, $_, $_] } 0 .. 1000000; print "done\n"; sleep 10;
4.7.2006 14:47 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
a este raz, ked je kluc unikatny vo vsetkych hash-och
  PID   RSS    VSZ CMD
 5921 439388 478164 perl -e '@list = map { {$_ => $_, $_+1000000 => $_, $_+2000000 => $_} } 0 .. 1000000; print "done\n"; sleep 10;'
4.7.2006 15:03 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Ten rozdíl v délce klíče mezi 1 a 10001 je příliš malý:
  PID   RSS    VSZ CMD
29161 260520 264708 perl -e @list = map +{1 => undef, 2 => undef, 3 => undef}, 0 .. 1000000; print "done\n"; sleep 10
29120 260532 264708 perl -e @list = map +{"a"x100 => undef, "b"x100 => undef, "c"x100 => undef}, 0 .. 1000000; print "done\n"; sleep 10
Což značí, že máte patrně pravdu. Tím se to dost podobá implementaci dict v pythonu.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
4.7.2006 15:20 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Jenže pro více klíčů už to tak jednoznačně nevyznívá
  PID   RSS    VSZ CMD
29709 487364 491560 perl -e @keys = map chr(ord("a")+$_)x100, 0..25; @list = map +{map +($keys[$_], undef), 0..25}, 0 .. 100000; print "don
29742 254184 258316 perl -e @keys = 0..25; @list = map +{map +($keys[$_], undef), 0..25}, 0 .. 100000; print "done\n"; sleep 10
Zdá se, že perl má svá tajemství. Uložení klíčů není tak neoptimální jak jsem si myslel, ale není to ani tak ideální jak jste tvrdil.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
4.7.2006 15:30 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Tak zas jinak, bacha na map, občas dělá něco jiného než by od něj člověk čekal
  PID   RSS    VSZ CMD
30214 83904  87972 perl -e @keys = map chr(ord("a")+$_)x100, 0..25; for($i=0; $i<100000;$i++){push @list,{map +($keys[$_], undef), 0..25}};
30218 83884  87964 perl -e @keys = 0..25; for($i=0; $i<100000;$i++){push @list,{map +($keys[$_], undef), 0..25}}; print "done\n"; sleep 10
Pravdu asi máte vy.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
4.7.2006 16:02 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array
Hmm, pravdu bude mat asi jedine Larry Wall :-)
  PID   RSS    VSZ CMD
 6271 109856 111536 perl -e @keys = 0..25; sub aaa { {map +($keys[$_], undef), 0..25}}; for($i=0; $i<100000;$i++){push @list,aaa }; print "done\n"; sleep 10
takze pravda bude niekde uprostred, asi zalezi na konexte, kde sa pole vytvori. No nic, idem hladat, kde som sa to vlastne docital.
4.7.2006 13:43 myšák | skóre: 26 | blog: EmentuX | Ostrava
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v array

Děkuji za vyčerpávající odpověď. Člověk se stále učí :-)

Je nesmírně těžké být idiotem, konkurence je obrovská...
4.7.2006 10:50 myšák | skóre: 26 | blog: EmentuX | Ostrava
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v seznamu?
Odpovědět | | Sbalit | Link | Blokovat | Admin

Možná jsem to blbě pochopil, ale není to tím, že používáš @seznam (tedy pole) místo %seznam (tedy hash)?

Je nesmírně těžké být idiotem, konkurence je obrovská...
4.7.2006 11:00 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v seznamu?
Odpovědět | | Sbalit | Link | Blokovat | Admin
mate na mysli nieco ako:
$a = 1;
$b = 2;

@seznam = ($a, $b);
a chcete aby vystup bol
a = 1
b = 2
?
pouzite radsej nasledovne:
$hash{a} = 1;
$hash{b} = 2;

# nezalezi na poradi
while (my ($a, $b) = each %hash) {
  print $a, $b, "\n";
}

# zalezi na poradi
for (sort keys %hash) {
  print $_, $hash{$_}, "\n";
}
4.7.2006 11:09 miso | skóre: 36 | blog: iSCSI_initiator_howto | Praha
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v seznamu?
Odpovědět | | Sbalit | Link | Blokovat | Admin
use Data::Dumper;

print Dumper(@seznam);

Ale pripajam sa k nazoru, ze zrejme nemas jasno v tom, co chces vlastne dosiahnut ;-)
Project Satan infects Calculon with Werecar virus
4.7.2006 11:40 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl - vypsat nazvy polozek v seznamu?
Tak s dumperem mě napadá taková hezká věc:
use Data::Dumper;
my $radek = <>;
my @array = my ($jmeno, $prijmeni, $telefon) = split ' ', $radek;
print Data::Dumper->Dump(\@array, [qw(jmeno prijmeni telefon)])
:-D
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.