我有以下两个哈希值。第一个是模板,第二个是用户设置。
我需要能够创建一个遍历第二个哈希的循环,如果它找到了差异(第一个中存在一个值而不是第二个中存在一个值),那么它需要对该键进行一些操作。价值(让我们说打印吧)
$VAR1 = {
'Hotkeys' => [
'key',
'keyCR',
'keyHighlight',
'updated'
],
'Actions' => [
'action',
'actionCR',
'actionHighlight'
],
'Settings' => [
'chbAcronym',
'chbCompleted'
],
'NewSetting' => [
'NewValue'
]
};
$VAR1 = {
'Hotkeys' => [
'key',
'keyCR',
'keyHighlight'
],
'Actions' => [
'action',
'actionCR',
'actionHighlight'
],
'Settings' => [
'chbAcronym',
'chbCompleted'
]
};
答案 0 :(得分:1)
迭代键并比较匹配键的数组。
sub my_special_hash_diff {
my(%hash_A,%hash_B) = (@_) ; #This may need some tweaking, you probably need
# need to pass in Hash references.
for $key ( keys %hash_B ) {
@array1 = $hash_B{$key} ;
@array2 = $hash_A{$key} ;
compare_2_arrays(@array1,@array2) ; # See answer below.
}
}
如何比较两个perl数组
答案 1 :(得分:1)
如果我正确理解您的问题,您只想在用户设置哈希中不存在模板哈希中的项目时,才能将模板哈希中的项目添加到用户设置'hash 。
我们可以利用Perl的Autovivification,如果该哈希中的项目不存在,它将在用户设置'哈希中创建完整的数据结构。请考虑以下事项:
use strict;
use warnings;
use Data::Dumper;
my %template = (
'Hotkeys' => [ 'key', 'keyCR', 'keyHighlight', 'updated' ],
'Actions' => [ 'action', 'actionCR', 'actionHighlight' ],
'Settings' => [ 'chbAcronym', 'chbCompleted' ],
'NewSetting' => [ 'NewValue' ]
);
my %userSettings = (
'Hotkeys' => [ 'key', 'keyCR', 'keyHighlight' ],
'Actions' => [ 'action', 'actionCR', 'actionHighlight' ],
'Settings' => [ 'chbAcronym', 'chbCompleted', 'aUserSetting' ]
);
updateUserSettings( \%template, \%userSettings );
print Dumper \%userSettings;
sub updateUserSettings {
my ( $templateHash, $settingsHash ) = @_;
for my $key ( keys %$templateHash ) {
$settingsHash->{$key}->[$_] //= $templateHash->{$key}->[$_]
for 0 .. $#{ ${$templateHash}{$key} };
}
}
输出('更新'后转储%userSettings
):
$VAR1 = {
'Hotkeys' => [
'key',
'keyCR',
'keyHighlight',
'updated'
],
'Actions' => [
'action',
'actionCR',
'actionHighlight'
],
'NewSetting' => [
'NewValue'
],
'Settings' => [
'chbAcronym',
'chbCompleted',
'aUserSetting'
]
}
请注意,%userSettings
仅在缺少%template
信息的情况下进行更新,并且不会打扰任何其他内容。
子例程updateUserSettings
使用Perl的 defined-或(//=
)运算符,因为它遍历%template
的所有键,因此%userSettings
如果键/值已经存在,则不会更改,否则会更新。
希望这有帮助!
答案 2 :(得分:0)
假设第一个散列(模板)包含第二个散列(模板)可能具有的所有可能值,您可以使用此方法,这可能不是最有效但很简单且不需要外部模块:
use strict;
my $template = {
'Hotkeys' => [
'key',
'keyCR',
'keyHighlight',
'updated'
],
'Actions' => [
'action',
'actionCR',
'actionHighlight'
],
'Settings' => [
'chbAcronym',
'chbCompleted'
],
'NewSetting' => [
'NewValue'
]
};
my $user = {
'Hotkeys' => [
'key',
'keyCR',
'keyHighlight'
],
'Actions' => [
'action',
'actionCR',
'actionHighlight'
],
'Settings' => [
'chbAcronym',
'chbCompleted'
]
};
#take all user keys so that we don't perform a join in each iteration
my $all_user_keys = join(' ',keys %$user);
#loop all template keys to see what's missing from user keys
foreach my $template_key( keys %$template ) {
#this will return a true value if the template key also exists in user hash
my $key_exists_in_user = ( $all_user_keys =~ m/$template_key/ );
#if it exists, perform a second loop for the values of the array
if ($key_exists_in_user) {
#take all user values so that we don't perform a join in each iteration
my $all_user_values_of_key = join(' ', @{$user->{$template_key}});
#loop all values of template key, to see what's missing from user values
foreach my $template_key_value (@{$template->{$template_key}}) {
#if value is not found, do what you want with it
unless( $all_user_values_of_key =~ m/$template_key_value/ ) {
print " -- value '$template_key_value' does not exist in user key '$template_key'. will add it now\n";
push @{$user->{$template_key}}, $template_key_value;
}
}
#else, hash key is not found, so do what you want with it
} else {
print "hash key '$template_key' does not exist in user settings. Will add it now\n";
$user->{$template_key} = $template->{$template_key};
}
}
我使用了你的示例哈希,我还假设你的哈希实际上是hashrefs(复制粘贴原样)