给定一串Key:Value对,我想创建一个查找哈希,但是键的小写值。我可以使用此代码
my $a="KEY1|Value1|kEy2|Value2|KeY3|Value3";
my @a = split '\|', $a;
my %b = map { $a[$_] = ( !($_ % 2) ? lc($a[$_]) : $a[$_]) } 0 .. $#a ;
生成的哈希看起来像这样的Dumper输出:
$VAR1 = {
'key3' => 'Value3',
'key2' => 'Value2',
'key1' => 'Value1'
};
是否可以在不使用临时数组@a的情况下直接创建哈希%b,还是有一种更有效的方法来实现相同的结果?
编辑:我忘了提到我不能为此使用外部模块。它必须是基本的Perl。
答案 0 :(得分:5)
您可以使用List :: Util中的pairmap来完成此操作,而无需任何中间数组。
use strict;
use warnings;
use List::Util 1.29 'pairmap';
my $str="KEY1|Value1|kEy2|Value2|KeY3|Value3";
my %hash = pairmap { lc($a) => $b } split /\|/, $str;
注意:切勿在排序(或List :: Util对函数)块之外使用$a or $b。它们是用于排序的特殊全局变量,仅在范围内声明my $a
可能会破坏该范围内的所有排序(以及List :: Util对函数)。一个简单的解决方案是,每当发现自己开始将它们用作示例变量时,立即用$x
和$y
替换它们。
答案 1 :(得分:2)
由于键值对必须位于|
附近,因此您可以使用正则表达式
my $v = "KEY1|Value1|kEy2|Value2|KeY3|Value3";
my %h = split /\|/, $v =~ s/([^|]+) \| ([^|]+)/lc($1).q(|).$2/xger;
答案 2 :(得分:1)
if (this.sourceList.some(x => x.Value === "L7") &&
this.selectedSources.some(x => x.Value === "L0")) {
...
}
输出:
use strict;
use warnings;
use Data::Dumper;
my $i;
my %hash = map { $i++ % 2 ? $_ : lc } split(/\|/, 'KEY1|Value1|kEy2|Value2|KeY3|Value3');
print Dumper(\%hash);
答案 3 :(得分:1)
为了娱乐,这里还有另外两种方法。
比原始便宜(因为元素被别名而不是复制到@_
中):
my %hash = sub { map { $_ % 2 ? $_[$_] : lc($_[$_]) } 0..$#_ }->( ... );
比原来的贵:
my %hash = ...;
@hash{ map lc, keys(%hash) } = delete( @hash{ keys(%hash) } );
答案 4 :(得分:1)
使用正则表达式来完成所有工作的更多可能解决方案,但是除非您非常喜欢正则表达式,否则不会很漂亮:
ptr[3]
答案 5 :(得分:0)
这里的解决方案避免了变异输入字符串,构造与输入字符串长度相同的新字符串或在内存中创建中间数组。
此处的解决方案将split
更改为对match语句的循环。
#! /usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my $a="KEY1|Value1|kEy2|Value2|KeY3|Value3";
sub normalize_alist_opt {
my ($input) = @_;
my %c;
my $last_key;
while ($input =~ m/([^|]*(\||\z)?)/g) {
my $s = $1;
next unless $s ne '';
$s =~ s/\|\z//g;
if (defined $last_key) {
$c{ lc($last_key) } = $s;
$last_key = undef;
} else {
$last_key = $s;
}
}
return \%c;
}
print Dumper(normalize_alist_opt($a));
直接在split
上运行的潜在解决方案。 Perl 可能可以识别并优化特殊情况。尽管基于讨论here和here,但我不确定。
sub normalize_alist {
my ($input) = @_;
my %c;
my $last_key;
foreach my $s (split /\|/, $input) {
if (defined $last_key) {
$c{ lc($last_key) } = $s;
$last_key = undef;
} else {
$last_key = $s;
}
}
return \%c;
}