首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较和验证数据结构

比较和验证数据结构
EN

Stack Overflow用户
提问于 2012-03-04 10:41:21
回答 2查看 381关注 0票数 5

我得检查一下像这个一样的hashrefs

代码语言:javascript
复制
{ foo => 65, bar => 20, baz => 15 }

针对一列表示这样条件的hashref

代码语言:javascript
复制
[
 { foo => { "<=" => 75 } },
 { bar => { "==" => 20 } },
 { baz => { ">=" => 5 } },
]

如果满足所有条件,则返回一个真值。

这两种数据结构都不是预先确定的。一个是通过解析数据库中的字符串构建的,另一个是通过解析用户输入构建的。

在上述情况下,我将返回true,但如果我检查hashref与

代码语言:javascript
复制
[
 { foo => { "<=" => 60 } },
 { bar => { "==" => 20 } },
 { baz => { ">=" => 5 } },
]

我会返回false,因为第一个hashref中的foo不是<= 60。

问题是:做这件事的最佳策略是什么?

我在想

  • 通过eval构建一系列次参考文献
  • 在5个不同的预构建子参中检查适当的子参( >、<、<=、>=和==)。

我是不是走错路了?如果不是,什么是最好的,最早的或预先构建的函数?

我研究了Params::Validate,但我担心这会导致大量开销,而且无论如何我都必须构建回调。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-04 11:21:22

改用代码引用,您就可以使用验证器了。我简化了你的条件-结构。这里不需要额外的数组级别,除非您有重复的散列键,我假设您没有。

简化的sub { $_[0] <= 75 }将简单地比较参数的第一个值。默认情况下,子例程中的最后一个值将是它的返回值。

代码语言:javascript
复制
use v5.10;
use strict;
use warnings;

my $in = { foo => 65, bar => 21, baz => 15 };

my $ref = {
    foo => sub { $_[0] <= 75 } ,
    bar => sub { $_[0] == 20 } ,
    baz => sub { $_[0] >= 5 } ,
};

for my $key (keys %$in) {
    if ($ref->{$key}($in->{$key})) {
        say "$key : Valid";
    } else {
        say "$key : Invalid";
    }
}

输出:

代码语言:javascript
复制
bar : Invalid
baz : Valid
foo : Valid
票数 7
EN

Stack Overflow用户

发布于 2012-03-04 12:33:59

为了基于TLP的答案,您还可以轻松地从现有的散列数组中创建匿名子类:

代码语言:javascript
复制
my $array_of_hashes = [
    { foo => { "<=" => 75 } },
    { bar => { "==" => 20 } },
    { baz => { ">=" => 5 } },
];

my $ref = {};
foreach my $entry ( @$array_of_hashes ) {
    my ($key, $subhash) = %$entry;
    my ($op, $num) = %$subhash;
    $ref->{$key} = {
        '<=' => sub { $_[0] <= $num },
        '==' => sub { $_[0] == $num },
        '>=' => sub { $_[0] >= $num },
    }->{$op};
}

这假设您只对原始散列数组中的每个字段进行一次检查。如果您有几个,事情会变得更棘手,但您总是可以这样做:

代码语言:javascript
复制
my $ref = {};
foreach my $entry ( @$array_of_hashes ) {
    my ($key, $subhash) = %$entry;
    my ($op, $num) = %$subhash;
    my $chain = $ref->{$key} || sub {1};
    $ref->{$key} = {
        '<=' => sub { $_[0] <= $num and $chain->($_[0]) },
        '==' => sub { $_[0] == $num and $chain->($_[0]) },
        '>=' => sub { $_[0] >= $num and $chain->($_[0]) },
    }->{$op} || $chain;
}

Ps。如果有人想知道这段代码如何工作,答案是:闭包。具体来说,当这些匿名子在循环中创建时,它们保留对词法变量$num$chain的引用,即使这些变量在当前循环迭代结束时超出了范围。因此,在此之后,这些变量将被安全地保存起来,只能从我们创建的子程序中访问。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9554206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档