0

Hashtbl を削除すると、以前のバインドが復元されるのはなぜですか。

Hashtbl.add t key1  
Hashtbl.remove t key1  
Hashtbl.remove t key1  => This should do anything but not restore the key1 !

とにかく、何かを確実に削除できるのはなぜですか。それが以前に削除された場合は、適切なフローに従う必要がありますか?

val remove : ('a, 'b) t -> 'a -> unit Hashtbl.remove tbl x は、tbl 内の x の現在のバインディングを削除し、以前のバインディングが存在する場合は復元します。x が tbl でバインドされていない場合は何もしません。

4

2 に答える 2

6

には 2 つの正当な使用方法がありますHashtbl。常に を使用してHashtbl.replace、各キーがテーブル内で 1 つのバインディングのみを持つようにするか、テーブルをマルチマッピング (各キーが値のリストを指す) として使用し、 と を使用Hasthbl.addHashtbl.findますHashtbl.find_all

関心のある使用モードを理解していることを確認してください。古いバインディングを保持したくない場合は、同じキーに複数のバインディングを追加しても意味がありません (これにより、パフォーマンスの問題、メモリ リーク、およびスタックが発生する可能性があります)。オーバーフロー); その場合、Hashtbl.replaceの代わりに を使用する必要がありHashtbl.addHashtbl.remove期待どおりに動作します。

ハッシュテーブルをマルチマッピングとして使用していて、キーのすべてのバインディングを削除する関数が必要な場合は、自分で実装できます (コードはテストされていません):

let rec remove_all tbl key =
  if Hashtbl.mem tbl key then begin
    Hashtbl.remove tbl key;
    remove_all tbl key
  end

編集:あなたの(理解しにくい)質問を読む別の方法は、remove「が呼び出されたときに黙って何もしないのではなく、テーブルに削除するキーがあることを確認するにはどうすればよいですか?」ということを理解しました。cago はそのためのコード スニペットを提供します。本質的にはHashtbl.mem、バインディングが存在すると想定しているときにバインディングが存在することを確認するために使用できます。

于 2013-01-30T12:28:16.250 に答える
2

Hashtbl.replaceの代わりに使用するとHashtbl.add、現在のキーのバインドが置き換えられtます。したがって、関数Hashtbl.removeは何も復元しません。

独自の remove 関数を書くこともできます:

let remove tbl key =
   if Hashtbl.mem tbl key then Hashtbl.remove tbl key
   else raise Nothing_to_remove_in_the_hashtbl

Hashtbl.replace t key1 value;;
remove t key1;;
remove t key1;;  (* raise Nothing_to_remove_in_the_hashtbl *)
于 2013-01-30T11:38:50.357 に答える