Как проверить, присутствует ли хеш-ключ в хэше, сопоставляя любую букву / цифру для символа {скажем X} - PullRequest
0 голосов
/ 13 января 2019

У меня есть хеш, скажем «Идентификатор» с такими ключами, как FACD, BDCD, DDSE, CDSD. Я хотел бы найти, присутствует ли ключ "FXXD" в хеш-коде "Идентификатор", считая, что X соответствует любому алфавитно-цифровому. В этом сценарии он должен возвращаться с найденными, поскольку "FXXD" соответствует "FACD", учитывая, что X может быть чем угодно.

Можно ли выполнить поиск по хеш-ключу, добавив символ, который соответствует чему-либо?

Любая идея была бы действительно полезна?

Заранее спасибо!

Ответы [ 4 ]

0 голосов
/ 14 января 2019

Если вы не слишком озабочены производительностью, вы можете использовать Tie :: Hash :: Regex .

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

use Tie::Hash::Regex;

my %hash : Regex;

%hash = (
  FACD => 1,
  BDCD => 1,
  DDSE => 1,
  CDSD => 1,
);

if (exists $hash{'F\w\wD'}) {
  say 'Found key matching FXXD';
} else {
  say 'No key matching FXXD';
}

[Полное раскрытие - я написал этот модуль как глупую демонстрацию связывания. Я действительно не рекомендую использовать его в производстве.]

0 голосов
/ 13 января 2019

Для выбора ключей, которые удовлетворяют шаблону

my @spec_keys = grep { /F..D/ } keys %identifier;

где шаблон F..D может находиться где угодно в ключе. Если он должен совпадать с ключом без каких-либо начальных или конечных символов, тогда закрепите его, /^F..D$/.

0 голосов
/ 13 января 2019

Сначала превратите X в вашей строке в класс символов регулярного выражения, который соответствует одному буквенно-цифровому символу, а затем старый добрый grep / keys:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw/say/;

my $test = { FACD => 1, BDCD => 1, DDSE => 1, CDSD => 1, QFADD => 1 };

sub matches {
  my ($hash, $key) = @_;

  # X matches all alphanumeric characters
  $key =~ s/X/[[:alnum:]]/g;
  my $pat = qr/^$key$/;
  return grep { m/$pat/ } keys %$hash;
}

for (qw/FXXD FXDD BXXX/) {
  say $_, (matches($test, $_) ? " matches!" : " doesn't match!");
}
0 голосов
/ 13 января 2019

Нет, ты не можешь. Одиночный хеш - неправильный подход для такого поиска.

Если ваши ключи имеют фиксированный размер, например 4 символа в соответствии с вашим примером, вы можете использовать несколько хешей. Вот эскиз алгоритма:

my %first = (
   A => { AAAA => 1, ... all keys starting with A... },
   ...
);
my %second = {
   A => { AAAA => 1, ... all keys having A as 2nd character... },
   ...
);
my %third  = ...
my %fourth = ...

# match first (F) and last (D) character in key
my $matches_first = $first{F};
my $matches_last  = $fourth{D};
my @matches =
    grep { exists $matches_fourth->{$_} }
    keys %{ $matches_first };

В реальной программе вы должны сгенерировать содержимое %first и т. Д. Из списка ключей и вычислить код совпадения из шаблона поиска.

foreach my $c ('A'..'Z') {
    $first{$c}  = {};
    $second{$c} = {};
    $third{$c}  = {};
    $fourth{$c} = {}; 
}
foreach my $key (keys %identifier) {
    my($c1, $c2, $c3, $c4) = split(//, $key);
    $first{$c1}->{$key}++;
    $second{$c2}->{$key}++;
    $third{$c3}->{$key}++;
    $fourth($c4}->{$key}++;
}

РЕДАКТИРОВАТЬ 2: В зависимости от объема ваших данных также может быть возможно использовать простую функцию поиска, например, для вашего примера

my @matches = grep { /^F..D$/ } keys %identifier; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...