参照変数の親配列を取得する方法

このQ&Aのポイント
  • 参照変数から親配列を取得する方法について質問しています。
  • 質問文章では、データの多次元配列の中で稀にキー値を使用したい場合があるため、中身の値だけを引数に渡す方法ではなく、親配列でのキー値を取得したいと考えていると述べています。
  • 現在は、処理が必要なデータ行に対してキー値を事前に入れる方法を使用しているが、より効率的な方法があれば知りたいとしています。
回答を見る
  • ベストアンサー

参照変数の親配列を取得

データの多次元配列があって、値に応じて動的に関数を選択し 中身の値を引数で渡すみたいな感じの処理をしています ほとんどの処理は中身の値だけあれば事足りるのですが 稀にキー値を使いたい処理がでてきます 本当に稀なので引数にキー値も渡すようにするのは 無駄が多くなるように思うので避けたく できれば参照変数で渡される値から 親配列でのキー値を取得したいと思っています $arr2A=array('a'=>array('fnc'=>'A','あ','い','う'),'b'=>array('fnc'=>'B','か','き','く'),'c'=>array('fnc'=>'C','さ','し','す')); $arr2B=array('a'=>array('fnc'=>'A','あ','い','う'),'b'=>array('fnc'=>'B','か','き','く'),'c'=>array('fnc'=>'C','さ','し','す')); $arr2C=array('a'=>array('fnc'=>'A','あ','い','う'),'b'=>array('fnc'=>'B','か','き','く'),'c'=>array('fnc'=>'C','さ','し','す')); foreach($arr2A as $key=>$val){ $fncs[$val['fnc']]($val); } foreach($arr2B as $key=>$val){ $fncs[$val['fnc']]($val); } foreach($arr2C as $key=>$val){ $fncs[$val['fnc']]($val); } $fncs=array( A=>function(&$arr){ }, B=>function(&$arr){ }, C=>function(&$arr){ //ここで稀にキー値も使いたい }); 実際のコードはかなり長いので載せられませんが 要約すると上記のような感じの処理です まずどのデータ配列の集合から渡されたのかが明確ではありませんので indexOfなどでキー値を得るのというのが難しいです 現在は、その処理が必要なデータ行について処理前に 中身にキー値をあらかじめ入れてしまう というように対応しているので、一応解決はしているのですが もし参照変数から親配列を得る方法が あればと思い質問させていただきました ”そんなものはない”という回答も あきらめつくのでお願いします

  • PHP
  • 回答数4
  • ありがとう数3

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

  • ベストアンサー
noname#244856
noname#244856
回答No.4

この設計だと A. 中身にキー値をあらかじめ入れてしまう B. 追加の引数として渡す のどちらかしかないですね。するしかないというか、こうするのが最も自然な実装になると思います。無駄とか気にする必要は無く。 蛇足ですが、書いてきたコードを整理するのであればもう少しOOPでまとめあげてもいい感じはしますね。Wordpressのように全てグローバル関数で書こうとするのは悪しき習慣なので倣う必要は無いです。

H240S18B73
質問者

お礼

ありがとうございます とりあえず現状すでにAの方法をとっているので これでいっとこうと思います

その他の回答 (3)

noname#244856
noname#244856
回答No.3

あとですね…ファンクショナルに書くと決めたら、「foreachは使わない」「全部コールバックとreturnで書く」ぐらい徹底したほうがスッキリしますね。動作速度を気にしていたらそもそもファンクショナルに書く云々以前にまずPHPを使いませんし。 【例】 <?php $input = [   'half_width_katakana' => [     'function' => 'to_full_width',     'data'   => ['ア', 'イ', 'ウ'], // 半角カナに直してください   ],   'full_width_katakana' => [     'function' => 'to_half_width',     'data'   => ['ア', 'イ', 'ウ'],   ], ]; $f = [   'to_full_width' => function ($v) {     return mb_convert_kana($v, 'KVS', 'UTF-8');   },   'to_half_width' => function ($v) {     return mb_convert_kana($v, 'kvs', 'UTF-8');   }, ]; $output = array_map(function ($v) use ($f) {   return [     'processed_by' => $v['function'],     'data' => array_map($f[$v['function']], $v['data']),   ]; }, $input); print_r($output);

H240S18B73
質問者

お礼

foreachのとこはウソですね、すいません より実態に近く書くなら foreachのところは echo hoge('a'); function hoge($name){ $arr2=get_current_arr2(); return $fncs[$arr2[$name]['fnc']](get_value_from_db($name),$arr2[$name]); } ってかんじのほうが近いです こういうことをしている目的は 出力の処理の手順の強制的な統一です 以前はDBからの出力のタイプが増えるたびに 関数を新たに書いていたのですが 処理の手順が違うために使い回しが効かなかったり 名前が違うだけで同じことやってるのがあったり 書いた本人さえもはやどんな関数書いたか覚えてないなど 収拾がつかなくなってきたので 今後の拡張を効率的にするためにも 柔軟性は捨てて窓口を一つにした感じです

noname#244856
noname#244856
回答No.2

(追記) もしforeachの記述と$fncsの記述が同じスコープ内にある場合、 function(&$arr) { ... } の部分を function(&$arr) use (&$key) { ... } にすれば参照出来なくもないです。但し関数的記述のセオリーからは大きく逸れてしまう上に、この上ない密結合になってしまいます。私ならば絶対採用しません。

noname#244856
noname#244856
回答No.1

そんな方法はありません。 というより、設計からしていろいろ問題がありそうな感じがしますね… 具体的な実装目的を提示していただければもうちょっとヒントが出せるかもしれません

H240S18B73
質問者

お礼

回答ありがとうございます 目的としては簡単に言うとDBからの出力の関数を データタイプによって動的に選択して出力する その際にいくつかの設定値も渡すというものです 例えばDBの値が画像IDであるなら その画像のURLをsrcに入れたimgのコードを出力する その際に出力サイズなどの設定値がはいった配列も渡す などといった感じです ほとんどの場合設定値さえ渡せば事足りるのですが 稀にキー値を使いたいものが出てくるという感じです

関連するQ&A

  • 配列の要素の値をループ中に変更して確認したいのですが、下記やり方では、

    配列の要素の値をループ中に変更して確認したいのですが、下記やり方では、なぜダメなのでしょうか? $arr = array("値1", "キー1" => "値2", "値3"); foreach($arr as $key => $val){ $arr[$key] = "-{$val}-"; echo $val."<br />"; } foreach($arr as $key => $val){ echo "<br />".$val; } 上のforeachの結果が、下と同じようになると期待したのですが、うまくいきません。 なんで、上のforeachと下のforeachの結果が異なるのでしょうか? foreach文で要素の値が更新されるのは、foreach文が終了した瞬間なのでしょうか。 それとも、値はすぐに更新されているけれども、foreach文の処理(順番に抽出する作業?)は既にスタートしてしまっているので、ループ中に更新されても、途中で反映することはできない、ということなのでしょうか? さっぱり分からないので、誰か教えてください。 「配列の要素の値をループ中に変更して確認したい」というよりは、 「なんで、二つのforeach文で結果が異なるか知りたい」です。

    • ベストアンサー
    • PHP
  • 2つの配列を再帰的に上書きでマージしたい

    array_merge_recursive では配列が同じ数値キーを有している場合、 後の値は元の値を上書せず、追加されます。 これを上書されるようにしたいのですが、どのようにすれば良いでしょうか? $arr3 = mymerge($arr1,$arr2); のような形で$arr3が得られると助かります。 $arr1,$arr2は再利用したいので書き換えられないようにしたいです。 次のような物をネット上で見つけたのですが、これでは$arr1が書き換えられてしまいます。 function mymerge(&$arr1,$arr2){ foreach ($arr2 as $key=>$value){ if(is_array($value)){ mymerge(&$arr1[$key],$value); }else{ $arr1[$key]=$value; } } return $arr1; } 次のようにすれば良いのかもしれませんが、1つのfunctionでできると助かります。 $temp1 = array(); $temp2 = mymerge($temp1,$arr1); $arr3 = mymerge($temp2,$arr2); いくら考えても分からないので、すみませんがどなたか教えてください。_○_

    • ベストアンサー
    • PHP
  • foreach文について、今朝、回答いただいて、その時は分かったつもり

    foreach文について、今朝、回答いただいて、その時は分かったつもりだったのですが、 やっぱりよく分かっていなかったようなので、もう一度質問させてください。 今朝質問した内容は、下記です。 ▼配列の要素の値をループ中に変更して確認したいのですが、   http://okwave.jp/qa/q5943567.html 例えば、下記例のとき、上記と挙動が異なるのは、なぜでしょう? このforeachでは、値を書き換えできないので、 そもそも、上記と比較をしてはいけないのでしょうか? $arr = array("値1", "キー1" => "値2", "値3"); foreach($arr as $val){ $val = "{$val}の値利用"; echo $val."<br />"; } foreach($arr as $val){ echo $val."<br />"; } 1)$arrの内容を$valにコピー 2)$valに値を代入 3)$valを表示 4)1)へ戻る で、特に分からないのが、以下です。 上のforeachで、 代入後の値が表示されるのは、 なぜでしょうか。 今朝質問した「$arr as $key => $val」 のときと比較して、 どなたか解説していただけないでしょうか?

    • ベストアンサー
    • PHP
  • 多次元配列の扱い方

    PHPバージョン5.2.4を使っています。 次のような文字列が入っている多次元配列を foreachなどのループを使ってその値を取り出して扱いたいのですが、 取り出した値には配列(二次元以降の値)も含まれてるので 簡単には取り扱いできません・・・ print_rやvar_dumpを使えば値は全て表示されるのですが、 あくまで表示ではなくて値を取り扱いたいのです。 そのようなことができる関数などはあるのでしょうか? $arr[0][0] = 'a'; $arr[0][1] = 'b'; $arr[1] = 'c'; $arr[2][0][0][0] = 'd'; $arr[2][0][0][1] = 'e'; foreach ($arr as $value) { $value//←ここで値を扱いたいけど、配列も含まれてるので・・・ }

    • 締切済み
    • PHP
  • 多次元配列を、1次元の配列にする関数を書いてください。

    以下のように、多次元配列の配列をペチャンコにする関数(array_flatten)ってどうかきますか? <?php $arr[0] = 'a'; $arr[1][0] = 'b'; $arr[1][1][0] = 'c'; $arr[1][1][1][0] = 'd'; $arr[1][1][1][1][0] = 'e'; $arr[1][1][1][2] = 'f'; $arr[1][1][2] = 'g'; $arr[1][2] = 'h'; $arr[2] = 'i'; function array_flatten($arg){   処理; } $new_arr = array_flatten($arr); print_r($new_arr); ?> ↓ Array (   [0] => a   [1] => b   [2] => c   [3] => d   [4] => e   [5] => f   [6] => g   [7] => h   [8] => i ) ※関数のなかで、ペチャンコの配列を格納するための新しい配列を宣言すると、 同関数を再帰的に呼び出したら、その配列が初期化されますよね?

    • ベストアンサー
    • PHP
  • 配列の初期化について(foreachを使う際)

    配列を、foreachの中で処理して、再び配列に入れたいです。 foreach ($a as $b) {   $tmp[]=処理($b); } ってやると、配列で取得できるのですが、 $tmp=array(); foreach ($a as $b) {   $tmp=処理($b); } ってやると、配列にならずに、 1つしかとれません。 どちらも、配列を初期化しているつもりなのですが、 $tmp=array();と、$tmp[]では、何が違うのでしょうか?

    • ベストアンサー
    • PHP
  • 配列型の宣言?

    こんにちは。 あるサイトで見たphpのサンプルなのですが、 postされた全ての値を配列に格納するもので、以下のような記述がありました。 foreach((array)$_POST as $key => $value){  $array[$key] = $value; } ポストされた全ての値を、配列$arrayに連想配列として格納しているのはわかるのですが、 foreachの、(array)というのはどういう働きをするものなのでしょうか。 これは、$_POSTが配列であるという宣言でしょうか。 それと、postされた値がない場合、$_POSTを配列だと宣言しておくことで、foreachのエラーを回避するような役割もあるのでしょうか。 恥ずかしながら、(array)のような記述をphpではあまり見ないような気がするのですが、なんというキーワード(?)で勉強すれば理解が深められるかもご教授頂けますと助かります。 宜しくお願い申し上げます。

    • ベストアンサー
    • PHP
  • Functionの戻り値を配列にしたいのですが

    vbを始めたばかりですがよろしくお願いします。 Functionの戻り値を配列にしたいのですが Function fnc(ByVal a As Byte, ByVal b As Byte) As Integer() fnc(0) = a + b fnc(1) = a - b End Function というような使い方はできないのでしょうか? 一つのFunctionで二つの計算結果をかえすには どうしたらよいのでしょうか? お願いします。

  • 多次元配列の形を保ちながら特定の箇所だけ値を変更

    PHP初心者 かつ 配列が苦手な私です。 勉強不足でありながら、助けを求めているのですが、どうにも時間がないので、どうかよろしくおねがいいたします。 多次元配列の形を保ちながら特定の箇所だけ値を変更したいのです。 $arrRet という多次元配列■Aを■Bのようにしたいのです。 つまり、キーがpriceだったらその値を消費税込の値にしたい のです。 $arrRet という名前は違う名前になってもかまいません。 ■A Array ( [0] => Array ( [date] = > 2012-06-01 11:11:11 [price] => 100 ) [1] => Array ( [date] = > 2012-06-02 22:22:22 [price] => 100 ) ) ■B Array ( [0] => Array ( [date] = > 2012-06-01 11:11:11 [price] => 105 ) [1] => Array ( [date] = > 2012-06-02 22:22:22 [price] => 105 ) ) ちなみに 消費税は$taxを使用します。 $taxの値は1.05が入っています。 こんな感じかな?と思うのですが、この後 なにをどうしたらよいのか全然わからないんです。 foreach($arrRet as $key1 => $aa) { foreach($aaas $key2 => $bb) { } } よろしくおねがいいたします!!

    • ベストアンサー
    • PHP
  • 配列を比較して同じものがあった場合にそのKEYを返す

    二つの配列を比較して同じ値が入っていた場合、そのKEYを配列に入れたいと思います。 (例)$aと$bを比較して同じ値が入っているときに$aのkeyを$cに格納したい。 $a = array("","","山","","川","海","","富士山","空","",""); $b = array("川","","","","","海","","富士山","空",""); ※空白は無視したい。 この場合 $c = array("4","5","7","8"); のようにしたいと思います。 どなたか教えてください。

    • ベストアンサー
    • PHP

専門家に質問してみよう