我有一个Perl DBM哈希,其中包含一个我想从随机选取的URL列表以加载平衡蜘蛛网站点。因此,我想随机选择一个键,或者选择第n个元素(这样我可以随机选择n)。如何访问Perl DBM哈希中的随机元素?
我知道这违背了散列的概念,但这可能吗?
注意:错过了一个有价值的观点,即散列大小将会过大,无法加载所有要随机选择的键。
我有一个Perl DBM哈希,其中包含一个我想从随机选取的URL列表以加载平衡蜘蛛网站点。因此,我想随机选择一个键,或者选择第n个元素(这样我可以随机选择n)。如何访问Perl DBM哈希中的随机元素?
我知道这违背了散列的概念,但这可能吗?
注意:错过了一个有价值的观点,即散列大小将会过大,无法加载所有要随机选择的键。
当然,这是可能的。首先,获取密钥列表。然后,使用来自List::Util的shuffle
随机化列表。
然后,循环按键。
如果密钥太多(因此将它们全部保存在列表中,并且不可能洗牌),请记住您正在使用并列哈希值。只需使用each
即可遍历键值对。
订单将是确定性的,但AFAIK,它不会是字母或插入顺序。这本身就可能让你得到你想要的东西。
从数组中挑选一个随机元素更简单,因此您可以使用keys(%foo)
来获取密钥数组并从中随机选取。
我相信这会从一个数组返回随机元素$x
:
$x = $array[rand @array];
如果你想洗牌的数组,考虑名单::的Util ::洗牌。请参阅http://search.cpan.org/perldoc/List::Util#shuffle_LIST
我不认为任何DBM软件包都有用于检索随机密钥或通过索引号检索密钥的API。您可以查找某个特定的密钥,也可以按照数据库选择的所有顺序读取所有密钥(如果数据库已修改,可能会发生变化,并且可能随机或不随机,无论您想要什么去做)。
你可以通读所有的键并选择一个,但是每次需要读取整个数据库(或者至少有相当一部分数据库),这可能太慢了。
我想你需要重新安排你的数据结构。
你可以使用一个真正的SQL数据库 (如SQLite),所以你可以 查找行都是由连续 行号和网址。这将是 是最灵活的。
您可以使用顺序整数 作为DBM文件的关键字。那 会随机挑选一个 容易,但你不能再通过URL查找 条目。
您可以使用两个DBM文件:一个是现在的文件,另一个是以URL为值的连续整数键入的。 (实际上,由于URL看起来不像整数,因此可以将两组记录存储在同一个DBM文件中,但这会使使用each
的任何代码复杂化。)这将使用两倍的磁盘空间,并且会使插入/删除条目更复杂一些。除非由于某些原因无法安装SQLite,否则你可能会更好地使用方法#1。
'真正的SQL数据库'的相关问题: http://stackoverflow.com/questions/19412/how-to-request-a-random-row-in-sql – plusplus 2010-01-28 09:34:58
您可以使用DBM::Deep而不是传统的DB文件来保存您的数据。
tie %hash, "DBM::Deep", {
file => "foo.db",
locking => 1,
autoflush => 1
};
# $hash{keys} = [ ... ]
# $hash{urls} = { ... } <- same as your current DB file.
my $like_old = $hash{urls}; # a ref to a hash you can use like your old hashref.
my $count = @{$hash{keys}};
这样就可以根据需要提取随机值。
您正在使用哪个DBM模块? – 2010-01-27 22:11:02
针对Windows构建的Perl 5.8.x中的标准DBM。对不起,我没有更多的细节。 – Paul 2010-01-27 22:17:39