如何访问Perl DBM哈希中的随机元素?

如何访问Perl DBM哈希中的随机元素?,perl,hash,random,dbm,Perl,Hash,Random,Dbm,我有一个Perl DBM散列,其中包含一个URL列表,我想从中随机选取这些URL来平衡爬网站点的负载。因此,我想随机选择一个关键点,或者选择第n个元素(这样我就可以随机选择n) 我知道这违背了散列的概念,但这可能吗 注意:忽略了一个有价值的点,即散列大小太大,无法加载所有要随机选择的键。当然,这是可能的。首先,获取密钥列表。然后,使用shufflefrom将列表随机化 然后,在键上循环 如果有太多的键(因此将它们全部保留在一个列表中,并且不可能进行洗牌),请记住您使用的是绑定哈希。只需使用每个迭

我有一个Perl DBM散列,其中包含一个URL列表,我想从中随机选取这些URL来平衡爬网站点的负载。因此,我想随机选择一个关键点,或者选择第n个元素(这样我就可以随机选择n)

我知道这违背了散列的概念,但这可能吗


注意:忽略了一个有价值的点,即散列大小太大,无法加载所有要随机选择的键。

当然,这是可能的。首先,获取密钥列表。然后,使用
shuffle
from将列表随机化

然后,在键上循环

如果有太多的键(因此将它们全部保留在一个列表中,并且不可能进行洗牌),请记住您使用的是绑定哈希。只需使用
每个
迭代键值对即可


顺序将是确定的,但请注意,它将不是字母顺序或插入顺序。这本身就可能让你得到你想要的东西。

当然,这是可能的。首先,获取密钥列表。然后,使用
shuffle
from将列表随机化

然后,在键上循环

如果有太多的键(因此将它们全部保留在一个列表中,并且不可能进行洗牌),请记住您使用的是绑定哈希。只需使用
每个
迭代键值对即可


顺序将是确定的,但请注意,它将不是字母顺序或插入顺序。这本身就可以满足您的需要。

从数组中选择随机元素更简单,因此您可以使用
键(%foo)
获取键数组并从中随机选择

我相信这将从数组中返回一个随机元素
$x

$x = $array[rand @array];

如果你想洗牌,考虑列表::UTI::洗牌。请参见

从数组中拾取随机元素更简单,因此可以使用
键(%foo)
获取键数组并从中随机拾取

我相信这将从数组中返回一个随机元素
$x

$x = $array[rand @array];

如果你想洗牌,考虑列表::UTI::洗牌。请参阅

我认为任何DBM包都没有用于检索随机键或按索引号检索键的API。您可以查找一个特定的键,也可以按照数据库选择的返回顺序读取所有键(如果数据库被修改,这可能会发生变化,并且对于您想要执行的任何操作来说可能“随机”得不够)

您可以通读所有键并选择一个,但这需要每次读取整个数据库(或者至少读取相当大的一部分),这可能太慢了

我认为您需要重新安排数据结构

  • 您可以使用真正的SQL数据库 (喜欢),所以你可以 按顺序查找两行 行编号和URL。这会 要最灵活

  • 可以使用顺序整数 作为DBM文件的密钥。那个 会让你随便挑一个吗 很容易,但你再也看不见了 按URL查找条目

  • 您可以使用两个DBM文件:一个是您现在拥有的,另一个是由URL作为值的顺序整数键入的。(实际上,由于URL看起来不像整数,您可以将两组记录存储在同一个DBM文件中,但这会使使用
    每个
    的任何代码变得复杂)这将占用两倍的磁盘空间,并且会使插入/删除条目变得更加复杂。除非出于某种原因无法安装SQLite,否则使用方法#1可能会更好


  • 我认为任何DBM包都没有用于检索随机键或按索引号检索键的API。您可以查找一个特定的键,也可以按照数据库选择的返回顺序读取所有键(如果数据库被修改,这可能会发生变化,并且对于您想要执行的任何操作来说可能“随机”得不够)

    您可以通读所有键并选择一个,但这需要每次读取整个数据库(或者至少读取相当大的一部分),这可能太慢了

    我认为您需要重新安排数据结构

  • 您可以使用真正的SQL数据库 (喜欢),所以你可以 按顺序查找两行 行编号和URL。这会 要最灵活

  • 可以使用顺序整数 作为DBM文件的密钥。那个 会让你随便挑一个吗 很容易,但你再也看不见了 按URL查找条目

  • 您可以使用两个DBM文件:一个是您现在拥有的,另一个是由URL作为值的顺序整数键入的。(实际上,由于URL看起来不像整数,您可以将两组记录存储在同一个DBM文件中,但这会使使用
    每个
    的任何代码变得复杂)这将占用两倍的磁盘空间,并且会使插入/删除条目变得更加复杂。除非出于某种原因无法安装SQLite,否则使用方法#1可能会更好

  • 您可以使用而不是传统的数据库文件来保存数据

    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}};
    
    tie%hash,“DBM::Deep”{
    文件=>“foo.db”,
    锁定=>1,
    自动刷新=>1
    };
    #$hash{keys}=[…]
    #$hash{url}={…}您可以使用它来代替传统的数据库文件来保存数据

    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}};
    
    tie%hash,“DBM::Deep”{
    文件=>“foo.db”,
    锁定=>1,
    自动刷新=>1
    };
    #$hash{keys}=[…]
    
    #$hash{url}={…}您正在使用哪个DBM模块?Perl 5.8.x中为Windows构建的标准DBM。对不起,我没有更多的细节。您使用的是哪个DBM模块?Perl 5.8.x中为Windows构建的标准DBM。抱歉,我没有更多详细信息。已经有
    List::Util::shuffle
    。请参阅,当List::Util中的一个更健壮(更快)时,无需编写自己的
    shuffle
    。感谢您的建议,这是一个可以管理哈希大小的解决方案。有没有其他方法可以让哈希值过大而无法加载所有键?有alread