我有一个包含非常大的单词(键)列表及其频率(值)的哈希 我的问题是,同一个单词可能会出现不同情况多次,如:
de => 14477841
la => 6577441
et => 5327316
PAR => 1670264
PaR => 1669878
PAr => 1669877
当发生这种情况时,我想在散列中找到同一个单词的所有不同版本,无论情况如何,并在合并它们的同时将这些值合并,所以在这里我得到:
de => 14477841
la => 6577441
et => 5327316
par => 5010019
(“par”是小写的,但我并不在意,只要它只有一个版本。)
我试图在数组中获取不同的键,并检查哈希中是否存在此列表的每个项目的不同版本。有许多不同的案例模式我无法想到并且难以预测。
以下是我的代码示例,它的价值(它部分有效但我仍然可以重复)
my %hashoutput;
my %hash = map { my ( $key, $value ) = split "\t"; ( $key, $value ) } @lignes;
foreach $ligne (@lignes) #list of keys and values separated by a tab
{
($cleorigine, $valeur) = split /\t/, $ligne; #get the key and value
$cle = $cleorigine =~ s/^([A-Z])/lc($1)/gr; # different versions of it
$clemaj = $cleorigine =~ s/^([a-z])/uc($1)/ge;
if ($cleorigine !~ /[0-9]{2}/g)
{
if ($ligne =~ /^([A-Z]|[ÉÈÊÂÀÙÛÇÔÎÏ])/g)
{
if (exists $hash{lc($cleorigine)})
{
$valeur1 = $valeur + $hash{lc($cleorigine)};
$hashoutput{ $cleorigine } = $valeur1;
}
if (not exists $hash{lc($cleorigine)})
{
if (exists $hash{$cle})
{
$valeur2 = $valeur + $hash{$cle};
$hashoutput{ $cleorigine } = $valeur2;
}
}
}
elsif ($ligne =~ /^([a-z]|[éèêâàùûçôîï])/g)
{
if (exists $hash{$clemaj})
{
}
elsif (not exists $hash{uc($clemaj)})
{
{
$hashoutput{ $cleorigine } = $valeur;
}
}
}
}
}
有更好/更简单的方法吗?
答案 0 :(得分:3)
通过聚合等效键的值
,从旧的哈希创建新哈希喜欢这个。请注意,数据将从原始哈希中删除,以节省空间。 fc
运算符执行Unicode大小写折叠,以便它可以处理非ASCII字符
use strict;
use warnings 'all';
use feature 'fc';
my %data = (
de => 14477841,
la => 6577441,
et => 5327316,
PAR => 1670264,
PaR => 1669878,
PAr => 1669877,
);
my %new_data;
$new_data{ fc $_ } += delete $data{$_} for keys %data;
use Data::Dump 'dd';
dd \%new_data;
{ de => 14477841, et => 5327316, la => 6577441, par => 5010019 }