• ベストアンサー

多次元連想配列の削除

初めまして、自分でhpを持ちたく、Perlの勉強をしておりますパールマンと申します。 連想配列の連想配列で、下記のような $nihon = {      'tokyo' => {            'setagaya' => 1,            'shibuya' => 1            },      'osaka' => {            'namba' => 1,            'kitashinchi' => 1            }, 多次元連想配列を作ったとして、 この「%nihon」自体を削除したいのですが、どのようにしたら良いのでしょうか? delete %nihon や undef %nihon としても、ループ処理でキーを取り出すと物が残っており困っています。 どうもこの多次元配列自体が「リファレンス」というもで、、、 delete %nihon や undef %nihon はスッゲェ見当外れ、つぅか%nihonは別モンですよ。みたいなとこまではボンヤリわかってきたのですが…。 よろしくお願い致します。

  • Perl
  • 回答数4
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • hara_peko
  • ベストアンサー率28% (11/38)
回答No.2

壱:print "$nihon{'tokyo'}{'nakano'}"; 弐:print "$nihon->{'tokyo'}->{'nakano'}"; この二つは別の物です。 壱は$nihon{'tokyo'}->{'nakano'} 弐は$nihon->{'tokyo'}->{'nakano'} です。 壱を${nihon}{'tokyo'}{'nakano'} とすれば同じになります。

その他の回答 (3)

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

消え残りについて Perlでは、その変数への参照がなくならないと確保されているメモリは解放れません。 なので、無名ハッシュのリファレンスが$nihonに代入されていて、 その内部の変数(メモリ)に他から参照がされていなければ、 $nihonをundefすることで、全体を解放することができます。 逆に言えば、なんらかの変数で、その内部に参照が残っていると、$nihonをundefしてもその内部の部分は解放されない場合があります。 おそらくは、そういうことではないでしょうか 例えば、以下のようにして試してみると、 undefの後で、ハッシュの中身が無くなっていることが確認できると思います。 #------------------------------------------------------------------- $nihon = { 'tokyo' => { 'setagaya' => 1, 'shibuya' => 2 }, 'osaka' => { 'namba' => 3, 'kitashinchi' => 4 }}; while(($key, $value) = each( %$nihon )){ print "$key:\n"; while(($k, $v) = each( %$value )){ print "\t$k:$v\n"; } } print "$$nihon{'tokyo'}{'shibuya'}\n"; undef $nihon; while(($key, $value) = each( %$nihon )){ print "$key:\n"; while(($k, $v) = each( %$value )){ print "\t$k:$v\n"; } }

perl_man
質問者

お礼

無事解決致しました。皆様本当にありがとうございました。 悩んだ要因は、 tie (%nihon,'MLDBM',"nihon.db",$mode,0640); として %nihon にデータベースを関連づけた場合、 print "$nihon{'tokyo'}->{'nakano'}"; で取り出せていたのですが、 このDBを print FILE Dumper(\%nihon); としてテキストファイルに出力していたものは、 $nihon = {'tokyo' => {'nakano' => 1,'shibuya' => 1}, 'osaka' => {'namba' => 1,'kitashinchi' => 1},}; という宣言文で出力されており、 このテキストファイルを取り込んだ別のcgiだと print "$nihon{'tokyo'}->{'nakano'}"; では取り出せず、 print "$nihon->{'tokyo'}->{'nakano'}"; でないと取り出せませんでした。 同様に tie で 取り込んだcgiでは undef %nihon で消えていましたが、 Dumperしたテキストファイルから取り込んだcgiでは undef $nihon で消えるという状態でした。 tie したものも Dumper で取り込んだものもまったく同じもんだと思っていました。 違うんですね、ちょっと意外でした。 良い勉強になりました、リファレンスについて勉強したいと思います。 ありがとうございました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.3

#1お礼>print "$nihon{'tokyo'}{'nakano'}"; えっとですね。 $nihonに格納されているのは、"無名ハッシュへのリファレンス"であるということを頭においておいて下さい。 なので、 print "$$nihon{'tokyo'}{'shibuya'}\n"; の様にアクセスします。 undefされた後で、存在しないデータにアクセスをするとそのこと自体が、新しい変数(ハッシュ)を作ってしまうことになるので注意して下さい。 例えば、質問文のようなハッシュのキーと値を取り出すには、次のようにしてみると良いかも知れません。 while(($key, $value) = each( %$nihon )){ print "$key:\n"; while(($k, $v) = each( %$value )){ print "\t$k:$v\n"; } }

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

$nihon に無名ハッシュのリファレンスが格納されているので、 undef $nihon; とすることで全体のハッシュを削除できます。 この場合、%nihonは、別物です。

perl_man
質問者

お礼

早速のご回答ありがとうございました。 試してみたのですが、なぜか消えるものと消えないものがございました…。 その法則性を探している時に見つけたのですが、 壱:print "$nihon{'tokyo'}{'nakano'}"; 弐:print "$nihon->{'tokyo'}->{'nakano'}"; このような2種類の書き方でprintしたときに、 壱の書き方じゃないと表示されない連想配列、 弐の書き方じゃないと表示されない連想配列、 はたまた壱でも弐でも表示されるものに分かれておりました。 何かに迷い込んだ気分です…。 壱と弐は同等と考えていたのですが、 違うのでしょうか?

関連するQ&A

  • 多次元配列を2次元の連想配列で表したい

    PHP初心者です。 $category = array( array( 'ライフ' ), array( 'デジタルライフ', array( '携帯・PHS' ), array( 'ワンセグ放送' ) ), array( '趣味', array( 'AV機器', array( 'オーディオ' ), ), ), ); このような多次元配列を $new_category = array( array( 'id'=> '1', 'parent_id' => '-', 'name' => 'ライフ', ), array( 'id'=> '2', 'parent_id' =>'-', 'name' => 'デジタルライフ', ), array( 'id'=> '3', 'parent_id' => '2', 'name' => '携帯・PHS', ), array( 'id'=> 4, 'parent_id' => '2', 'name' => 'ワンセグ放送', ), array( 'id'=> 5, 'parent_id' => '-', 'name' => '趣味', ), array( 'id'=> '6', 'parent_id' => '5', 'name' => 'AV機器', ), ); このような二次元配列に変換したいです。 parent_idを入れておく配列を作って、階層が深くなったら前の要素のIDを配列に入れ、浅くなったら配列の末尾の要素を消去する…みたいなことを考えてあれこれやってみたのですが、なかなかうまくいきません。 何か良い方法がありましたら、教えていただけるとありたがいです。 よろしくお願い致します。

    • ベストアンサー
    • PHP
  • 多次元連想配列

    phpで $juices["apple"]["green"] = "good"; このように多次元連想配列を簡単に生成できますが、javaでは、どのように行えばいいのでしょうか? いろいろな方法があると思われるのですが、javaでこのような多次元連想配列をスマートに実現する方法をご教授いただきたく質問させていただきました。

    • ベストアンサー
    • Java
  • 2次元の連想配列を順次読み込みするには?

    PHP初心者です。 元の連想配列($ary1)   Array ( [2004] => Array ( [03] => 03 [02] => 02 ) [2003] => Array ( [12] => 12 ) ) $ary1の値だけを$ary2に抽出する。   $ary2 = array_values($ary1); すると、こんな内容になります。   Array ( [0] => Array ( [03] => 03 [02] => 02 ) [1] => Array ( [12] => 12 ) ) ここまで来ると上位階層は$ary2[0]、[1]で読めそうですが、 下位階層まで考えると$ary2[0][03]、$ary2[0][02]になっています。 これを$ary2[0][0]、$ary2[0][1]という風に順次読み込みたいのですが、 いい方法が見つかりません。 つまり2次元の下位階層も[0]~のインデックスとしたいのです。

    • ベストアンサー
    • PHP
  • 多次元配列を連想配列へ変換したい

    以下のような多次元配列を、 Array ( [0] => Array     (     [0] => Array       (         [id] => 3         [hoge_id] => 15       )     ) [1] => Array   (     [0] => Array       (         [id] => 9         [hoge_id] => 15       )   ) [2] => Array   (     [0] => Array       (         [id] => 18         [hoge_id] => 15       )   ) [3] => Array   (     [0] => Array       (         [id] => 22         [hoge_id] => 15       )     [1] => Array       (         [id] => 22         [hoge_id] => 15       )     [2] => Array       (         [id] => 22         [hoge_id] => 15       )   ) ) 下記のような連想配列へ変換したいです Array (     [0] => Array       (         [id] => 3         [hoge_id] => 15       )     [1] => Array       (         [id] => 9         [hoge_id] => 15       )     [2] => Array       (         [id] => 18         [hoge_id] => 15       )     [3] => Array       (         [id] => 22         [hoge_id] => 15       )     [4] => Array       (         [id] => 22         [hoge_id] => 15       )     [5] => Array       (         [id] => 22         [hoge_id] => 15       ) )

    • ベストアンサー
    • PHP
  • 連想配列の削除

    始めまして hirohiroOracle(名前は特に気にしないで下さい^^;) といいます。どうしてもわからない事がありこちらの方に書き込みさせて いただきました。 JAVASCRIPTでは var objValue=new array(); objValue("DATA1")=1000; objValue("DATA2")=2000; ..... と連想配列を使用する事が出来ますが for (properName in objValue) { alert(objValue[properName]); } の中で一度配列に追加したものを削除し 表示させなくするには どのようにすればよろしいでしょうか? objValue("DATA1")=undefind; としてもプロパティ自体は 残ってしまうらしく 消せません。ブラウザはIE限定のScript なのですが。皆様よろしくお願いします。

  • 2次元の連想配列を検索できません。

    以下の2次元配列でstatusが2の配列(orange)だけを 返したいのですがPHPでどう組めば実現できるでしょうか? Array ( [orange] => Array ( [start_date] => 20041122 [status] => 2 ) [apple] => Array ( [start_date] => 20041123 [status] => 1 ) ) foreach()とかやってみているのですが、はまってます(T_T)

    • ベストアンサー
    • PHP
  • 多次元連想配列 検索 削除 最大値 得たい

    多次元連想配列をテーブルの様に使用しおり data[0] id => 1 day => 20130201 title=> あああああ data[1] id => 2 day => 20130202 title=> いいいいい data[2] id => 3 day => 20130203 title=> うううううう data[3] id => 6 day => 20130206 title=> えええええ data[4] id => 7 day => 20130207 title=> おおおおお id が 2 のデータを削除する (idが2の配列番号を知る) id の 最大値を得る (追加用のID番号にしたい) この場合どの様にすればよいのでしょうか 関数一発ではできない事は分かったのですが、どうした方法があるのでしょうか また、SQLなどを使わない方法で この様に配列をテーブルに使用する方法はあまりネットに載っていないように感じるのですが 良くないのでしょうか 用途は簡単なブログ作成です。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • 二次元配列の削除

    下記のような二次元配列になったファイル名"abc"があります 1,ab,4500,あ, 2,sd,1000,え, 3,df,500,お, 4,ef,200,い, リストの4番目のひらがな部分を削除したいのですが よろしくお願いします。

    • ベストアンサー
    • PHP
  • uasort()でクラスのメソッドは呼べますか?

    2次元連想配列の指定項目をソートするのに、uasort()を使いたいのですが、 uasort()で指定する関数に任意の引数は渡せず、固定の項目しかソートできません。 uasort($rensouArray,"comparar"); 関数ではなくクラスのメソッドが指定できば引数を渡せなくてもクラスのプロパティで渡せると思いましたが、 以下の書き方ではクラスのメソッドは呼べませんでした。 uasort($rensouArray,$this->$comparar()); http://jp.php.net/manual/ja/function.uasort.php の注意書きで、関数名の代わりに、オブジェクトへのリファレンスを格納した配列とメソッド名を指定することも出来ます。とありますが、書き方がわからず困っています。

    • 締切済み
    • PHP
  • 2次元連想配列配列の使用方法

    こんばんは。 次のような配列 "http://www.yahoo.co.jp", "Yahoo!" "http://www.google.co.jp", "google" (...以下同様...) で aryLink[0]["URL"] → "http://www.yahoo.co.jp" aryLink[1]["Text"] → "google" というように参照できるようにしたいのですが 下記のスクリプトで「'aryLink[...]'はまたはオブジェクトではありません」というエラーになってしまいます。 どうすればよいのでしょうか?教えてください。 よろしくお願いします。 -- var DEBUG=1; aryLink = new Array(2); for (i = 0; i < aryLink.length; i++) { aryLink[i] = new Array(); } var IE = WScript.CreateObject("InternetExplorer.Application"); IE.Navigate("http://www.yahoo.co.jp"); while(IE.busy); while(IE.Document.readyState != "complete"); var objTagsAs = IE.Document.all.tags("A"); if(DEBUG) { for (i = 0; i < 5; i++) { WScript.Echo(objTagsAs[i] + "," + objTagsAs[i].innerText); } } for (i = 0; i < objTagsAs.length; i++) { aryLink[i]["URL"] = String(objTagsAs[i]) aryLink[i]["Text"] = String(objTagsAs[i].innerText); }

専門家に質問してみよう