我有一個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