不区分大小写搜索哈希中的多个匹配项,合并键并添加值

时间:2017-03-29 14:58:34

标签: perl hash

我有一个包含非常大的单词(键)列表及其频率(值)的哈希 我的问题是,同一个单词可能会出现不同情况多次,如:

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;
                }
            }

        }
    }
}

有更好/更简单的方法吗?

1 个答案:

答案 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 }
相关问题