考虑以下问题:
$h = {
a => {
1 => x
},
b => {
2 => y
},
...
}
有没有办法在不调用keys(%$h)
的情况下检查第二个嵌套级别上是否存在哈希键?例如,我想说的是:
if ( exists($h->{*}->{1}) ) { ...
(我意识到你不能使用*
作为哈希键通配符,但是你明白了......)
我正在尝试避免使用keys()
,因为它会重置哈希迭代器,并且我在循环中使用以下代码$h
进行迭代:
while ( (my ($key, $value) = each %$h) ) {
...
}
我能找到的最接近的语言构造是smart match operator (~~
) mentioned here(并且在perlref perldoc中没有提到),但即使在Perl版本中~~
可用,我也被限制使用(5.8 .4),从我可以说它在这种情况下不起作用。
如果无法完成,我想我会在进入while
循环之前将密钥复制到数组或哈希中(这就是我的开始),但我希望避免开销。 / p>
答案 0 :(得分:3)
不是真的。如果你需要这样做,我想我会创建一个合并的哈希,列出所有二级密钥(在开始你的主循环之前):
my $h = {
a => {
1 => 'x'
},
b => {
2 => 'y'
},
};
my %all = map { %$_ } values %$h;
然后您的exists($h->{*}->{1})
变为exists($all{1})
。当然,如果你在循环中修改二级哈希值,这将不起作用(除非你适当地更新%all
)。该代码还假设$h
中的所有值都是hashrefs,但如果需要,这很容易修复。
答案 1 :(得分:2)
没有。 each
使用哈希的迭代器,你不能在不使用迭代器的情况下迭代哈希,即使在C API中也是如此。 (这意味着智能匹配无论如何也无济于事。)
由于每个哈希都有自己的迭代器,因此必须在使用keys
迭代的相同哈希上调用each
才能遇到此问题。既然您在该哈希上调用keys
没有问题,那么您只需使用keys
代替each
吗?或者可以调用keys
一次,存储结果,然后迭代存储的密钥?
答案 2 :(得分:1)
您几乎肯定会发现聚合二级哈希的“开销”小于任何其他解决方案的“开销”。每次要进行检查时,简单的哈希查找比遍历整个数据结构要快得多。
答案 3 :(得分:0)
你试图在没有任何while循环的情况下这样做吗?您可以仅通过引用来测试哈希中的存在,而不会生成错误
while ( my ($key, $value) = each %{$h} ) {
if ($value->{1}) { .. }
}
答案 4 :(得分:-1)
为什么不在Sybase本身而不是Perl中执行此操作?
您正在尝试进行集合操作,这是Sybase首先要构建的。
假设您从表中检索了数据“key1”,“key2”,“valye”为“select *”的数据,只需执行以下操作:
-- Make sure mytable has index on key1
SELECT key1
FRIN mytable t1
WHERE NOT EXISTS (
SELECT 1 FROM mytable t2
WHERE t1.key1=t2.key1
AND t2.key2 = 1
)
-----------
-- OR
-----------
SELECT DISTINCT key1
INTO #t
FROM mytable
CREATE INDEX idx1_t on #t (key1)
DELETE #t
FROM mytable
WHERE #t.key1=mytable.key1
AND mytable.key2 = 1
SELECT key1 from #t
任一查询都返回一个没有key2为1的第一级密钥列表