数组以哈希转换和打印相应的数组

时间:2016-12-12 17:46:27

标签: perl

我一直在尝试编写一个Perl脚本来获取用户输入名称并将它们存储在哈希值中。

我使用了以下代码,但显示错误。

这是我想回答的问题

  

在一行中将用户名称设为first_name<space >last_name   接受这样的多个用户数据,直到输入退出为止   通过将姓氏作为键,将名字作为值
,将此数据存储在哈希%emp中   以lastnames的升序排序顺序显示用户数据。

我假设姓氏是独一无二的

my $name; 
print "enter name:\n"; 

while ( my $name = lc <STDIN> ) { 
    chomp $name; 
    print "you entered: $name\n"; 

    push @n, $name; 
    last if ( $name eq 'exit' ); 

    $count++; 
    print "enter name :\n"; 
} 

print "count = $count\n"; 

my $r = pop @n;
print "@n\n";

my ($key, $value) = split(' ', @n); 
$emp{$key} = $value; 

while ( my ( $key, $value ) = each %emp ) { 
    my $value; 
    print "$key :$value\n"; 
}

我想要代码修正。

2 个答案:

答案 0 :(得分:0)

首先,警告 - 解析名称通常非常困难。下面的所有代码都严格假设每个名称由两个由空格分隔的单词组成。另请注意,如果没有检查,您完全可以让用户按预期输入他们的姓名。

您希望my ($key,$value) = split(' ',@n);分割@n的每个元素,并通过以下分配以某种方式创建整个哈希值。 split不适用于列表,但它需要一个字符串。但是,您可以使用map

完成此操作
my %emp = map { split } @names;  # names must be [word space(s) word]

我将您的数组名称从@n更改为@namesmap获取列表并一次将块{ }中的代码应用于一个元素,并返回已处理的列表。这被分配给%emp,因为哈希是一个列表,所以可以做什么。见perldata。 由于( if )每个split生成两个元素,因此获得的散列具有正确的配对。此处split使用其默认值,因此splitsplit ' ', $_相同,其中' '表示任意数量的空格。

我重复警告,一般的名称不包含两个单词。所以上述内容在任何意义上都不稳健,但它是一种通用的技术。

更灵活的方法是遍历您的名单

my %emp;

foreach my $name (@names) 
{
    my ($first, $last) = split ' ', $name;

    if ($first and $last) {
        $emp{$last} = $first;
    }
    else {
        # print a message, or store 'bad' name on an array
    }
}

print "$_, $emp{$_}\n" for sort keys %emp;

您应该添加对提交的名称格式的彻底检查。作为一个提示,我添加了一个非常简短的检查,检查split是否产生了(至少)两个单词。

您可以通过编写如何处理元素并将其放入块map的例程来对my %emp = map { process_name($_) } @names;执行相同的操作。但是,错误处理将更加困难。

鉴于需要检查用户输入,最好在上面的循环中处理名称,但在输入时,如果格式错误,可以再次提示用户。

答案 1 :(得分:0)

my @n;
loop: while(1) { # get your data with while named as "loop"
    print "enter name: ";
    chomp(my $i = <STDIN>);
    last loop if ($i eq "exit"); # enter to break the "loop"
    push @n, lc $i
}

printf "count = %d\n", $#n + 1;

my %emp = map {
    # split by space and get only first and secound
    my @p = (split)[0,1];
    # check here if everything is defined
    if (defined $p[0]) {
        # add this as key and value
        @p
    } else {
        # skip (this part is important)
        ()
    }
} @n; # converted to hash

my $p = {%emp}; # converted to {hash}ref

甚至

my %emp;
while(1) {
    print "enter name: ";
    chomp(my $i = <STDIN>);

    last if ($i eq "exit");

    my ($k, $v) = split q{ }, lc $i;
    defined $k
        and defined $v
        and $emp{$k} = $v;
}

printf("count = %d\n", scalar keys %emp);