2009-12-16 9 views

Odpowiedz

33

firstidx funkcja z List::MoreUtils może pomóc:

use strict; 
use warnings; 
use List::MoreUtils qw(firstidx); 

my @nums = ('830974', '722065', '722046', '716963'); 
printf "item with index %i in list is 722065\n", firstidx { $_ eq '722065' } @nums; 

__END__ 
 
item with index 1 in list is 722065 
+6

Lubię korzystać z Listy :: WięcejZadania, dobra odpowiedź! – chollida

+1

Korzystanie porównanie numeryczne z ciągów znaków nie jest dobrym pomysłem (chociaż to nie ma znaczenia w tym przypadku. Co się dzieje, gdy masz kody pocztowe i '07030' na liście.' Perl -e „print 0 + (07030 == "07030") "' –

+0

@Sanan: masz rację. Edytowałem swoją odpowiedź, aby wykonać porównanie ciągów. – toolic

3

Tutaj się pośpiesznie napisane próbę odwrotny look-up przy użyciu skrótu.

my $VAR1 = [ '830974', '722065', '722046', '716963' ]; 

my %reverse; 
$reverse{$VAR1->[$_]} = $_ for 0 .. @$VAR1 - 1; 

print $reverse{722065}; 

Nie uwzględnia to tablic z duplikatami wartości. Nie popieram tego rozwiązania dla kodu produkcyjnego.

+0

W przypadku zduplikowanych wartości otrzymasz pierwszy dopasowany element. Może to być bardzo przydatne, jeśli długo żywa tablica jest sprawdzana więcej niż raz. –

+2

Nie jestem pewien, czy rozumiem powyższy komentarz, ale sposób zapisania kodu, w przypadku zduplikowanych wartości, wygrywa najwyższy indeks. –

1

Zapoznaj się dyskusja na perlmonks: http://www.perlmonks.org/?node_id=66003

+0

Należy pamiętać, że jest to link do konkursu ** golf **. Podczas gdy strona z linkami przedstawia różne algorytmy i techniki o znacznej wartości pedagogicznej, należy zachować ostrożność przy dostosowywaniu tego kodu do użytku produkcyjnego. Pamiętaj, że ** golf ** jest oceniany głównie na podstawie najmniejszej liczby znaków - nie jest to dobry sposób na przemyślenie swojego kodu produkcyjnego. – daotoad

1

Zapoznaj się z Perl FAQ

+6

Wszyscy powinni przeczytać listę często zadawanych pytań przynajmniej raz w roku. –

+3

RRTFM-ing (Ponowne czytanie dobrej instrukcji) jest niezwykle satysfakcjonującym doświadczeniem. Po raz pierwszy przeczytałem dokumenty, wiele z nich poszło mi prosto w głowę. Każde kolejne czytanie ujawniło nowe znaczenie. To niesamowite, ile rzeczy możesz się nauczyć przez (ponowne) przeczytanie instrukcji! – daotoad

+2

Byłbym usatysfakcjonowany, gdyby większość ludzi przynajmniej raz to przeczytała. Ludzie ciągle pytają, jak istotne są najczęściej zadawane pytania, a StackOverflow był wspaniałym naturalnym eksperymentem: każdy ponownie zadaje pytania FAQ. –

14

Oto w jaki sposób można znaleźć wszystkie pozycje, w których pojawia się dana wartość:

#!/usr/bin/perl 

use strict; 
use warnings; 

my @x = (1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1); 
my @i = grep { $x[$_] == 3 } 0 .. $#x; 
print "@i\n"; 

Jeśli potrzebne jest tylko pierwszy indeks, należy użyć List::MoreUtils::first_index.

+1

Szczerze. Stracić wzmiankę o $ [. Jest to niejasne, przestarzałe IIRC i nie ma żadnego uczciwego powodu, aby go używać. – tsee

+1

@Zobaczyć Ci rację. Głupio było mi nawet wspomnieć o '$ [. –

+2

To materiał z Perl Street cred, pomyślałem :-) –

-7

to jest w porządku, każdy był nowy w perl w jednym punkcie

$ a jest elementem wydrukować indeks w @list ...

my @list = (124124, 323, 156666, 124412, 3333, 4444444444, 124124124, 24412); 
my $a = 4444444444; 

print 
substr($_=($,= 
chr($==39)).(
join$,,@list).$,,$=-$=, 
index$_,$,.$a.$,)=~ 
tr/'//+$=---$=; 
+0

Błąd off-by-one? Wydaje "6", ale spodziewam się "5". – toolic

+8

Jeśli Twoim celem jest pomoc początkującym, nie powinieneś publikować zaciemnionego kodu. Jeśli Twoim celem jest zaimponowanie ludziom, możesz poprawnie napisać Perl. –

+0

@toolic: jest to 6 element listy, nie zacząłem od 0, jeśli chcesz zacząć od 0, musisz zmienić ostatnią linię na tr/'// + $ = - $ =; – John

7

Jeśli tylko trzeba spojrzeć w górę jeden przedmiot, użyj firstidx, jak powiedzieli inni.

Jeśli trzeba zrobić wiele wyszukiwań, budowania indeksu.

Jeśli elementy tablicy są wyjątkowe, budowania indeksu jest dość prosta. Ale nie jest trudniej zbudować taki, który obsługuje duplikaty przedmiotów. Przykłady zarówno wykonaj:

use strict; 
use warnings; 

use Data::Dumper; 

# Index an array with unique elements. 
my @var_uniq = qw(830974 722065 722046 716963); 
my %index_uniq = map { $var_uniq[$_] => $_ } 0..$#var_uniq; 

# You could use hash slice assinment instead of map: 
# my %index_uniq; 
# @index_uniq{ @var_uniq } = 0..$#var_uniq 

my $uniq_index_of_722065 = $index_uniq{722065}; 
print "Uniq 72665 at: $uniq_index_of_722065\n"; 
print Dumper \%index_uniq; 

# Index an array with repeated elements. 
my @var_dupes = qw(830974 722065 830974 830974 722046 716963 722065); 
my %index_dupes; 
for(0..$#var_dupes) { 
    my $item = $var_dupes[$_]; 

    # have item in index? 
    if($index_dupes{$item}) { 
     # Add to array of indexes 
     push @{$index_dupes{$item}}, $_; 
    } 
    else { 
     # Add array ref with index to hash. 
     $index_dupes{$item} = [$_]; 
    } 
} 

# Dereference array ref for assignment: 
my @dupe_indexes_of_722065 = @{ $index_dupes{722065} }; 

print "Dupes 722065 at: @dupe_indexes_of_722065\n"; 
print Dumper \%index_dupes; 
24

użyciu List::Util, który jest moduł podstawowy, w przeciwieństwie List::MoreUtils, który nie jest:

use List::Util qw(first); 

my @nums = ('830974', '722065', '722046', '716963'); 
my $index = first { $nums[$_] eq '722065' } 0..$#nums; 
0
use strict; 
use Data::Dumper; 

sub invert 
{ 
my $i=0; 
map { $i++ => $_ } @_; 
} 

my @a = ('a','b','c','d','e'); 

print Dumper @a; 

print Dumper invert @a; 
+1

używać strict; use Data :: Dumper; sub lustro { \t my $ i = 0; \t mapa {$ i ++ => \ $ _} @ {shift @_}; } my @a = ("a", "b", "c", "d", "e"); my% b = mirror \ @a; print Dumper @a; print Dumper% b; $ a [1] = 'whoa ...'; print Dumper @a; print Dumper% b; $ a [3] = 'IKNOWRIGHT!'; print Dumper @a; print Dumper% b; – user549325

Powiązane problemy