別の配列を使用して多次元配列のキーを検索する

検索するキーの別の配列を使用して大規模な多次元配列から値を取得するエレガントな方法はありますか?

例えば

$cats[A][A1][A11][A111] = $val;
$cats[A][A1][A11][A112] = $val;
$cats[A][A1][A12] = $val;
$cats[A][A1][A12][A121] = $val;
$cats[A][A2] = $val;
$cats[A][A2][A21] = $val;
$cats[A][A2][A22] = $val;
$cats[A][A2][A22][A221] = $val;
$cats[A][A2][A22][A222] = $val;

access values from $cats using $keys = Array ('A', 'A2', 'A22', 'A221');

$ keys の長さをチェックせずに、次のようなことをすることなく

switch (count($keys)) {
   case 1: $val = $cats[$keys[0]]; break;
   case 2: $val = $cats[$key[0]][$key[1]]; break;
   case 3: $val = $cats[$key[0]][$key[1]][$key[2]]; break;
   ...
}

どうもありがとう。

0

3 答え

それは今のところうまくいきます。それ以外の場合は、配列を繰り返して深みをチェックする必要があります。動的にするために、$ catsを構築するときに$ keys配列にキーを追加することを確信しています。再帰を使用しても、より多くのステップとメモリが必要になります。

0
追加された

jburbageの再帰使用の提案は原則としてOKですが、私が知っていることから、PHPは終了再帰をサポートしていません。

そして、問題は「大規模な」多次元配列についてでした。

「大規模」は大きな全体のサイズに加えて深みが大きいことを示唆しているので、このソリューションではスタックのオーバーフローに遭遇する可能性があります。通常、ヒープ上に、スタックが再帰経由で対処できるよりも深く到達するデータ構造を作成できます。

このアプローチは、この場合パフォーマンスの観点からも望ましくない。

単純にjburbageの再帰的なソリューションをループで動作させるためにリファクタリングするだけで、あなたはほぼそこにいます:-)

jburbageのオリジナルのコードがもう一度表示されます:

function get_val($array, $keys) {
    if(empty($keys) || !is_array($keys) || !is_array($array)) return $array;
    else {
        $first_key = array_shift($keys);
        return get_val($array[$first_key], $keys);
    }
}
0
追加された
大規模な...うまくその唯一の猫は6深さになります
追加された 著者 Rob Curle,
OK、6つのレベルについては、実際には違いはありません:-)
追加された 著者 yeoman,
Btw、@jburbage:うわー、私はPHPが今や終わりの再帰を持っていることを知らなかった - 言語が本当に育っているように思える:-)
追加された 著者 yeoman,

再帰を使わないのはなぜですか?このようなもの:

function get_val($array, $keys) {
    if(empty($keys) || !is_array($keys) || !is_array($array)) return $array;
    else {
        $first_key = array_shift($keys);
        return get_val($array[$first_key], $keys);
    }
}

私はもともとこれをループで書いていましたが、何らかの理由で再帰的に変更しました。なぜなら、あなたの配列が十分に大きい場合(PHPが終了再帰をサポートしている場合)、同じ目的を達成する必要があるループがあることです。これは、反復関数がループよりもスタックオーバーフローを引き起こす可能性が高いということです。

// given a multidimensional array $array and single-dimensional array of keys $keys
$desired_value = $array;
while(count($keys) > 0) {
    $first_key = array_shift($keys);
    $desired_value = $desired_value[$first_key];
}
0
追加された
クール、私は見てみましょう..歓声
追加された 著者 Rob Curle,
配列要素$ cats [A] [A2] [A22] [A221]が存在しない場合は、追加したいと思います。その場合、上記のループはnullを返しますか?
追加された 著者 Rob Curle,
まことにありがとうございます
追加された 著者 Rob Curle,
今私は設定機能を書くのに苦労している! $ cats [A] [A2] [A22] [A221]の値を同じ2つの配列を使って設定する
追加された 著者 Rob Curle,
それはnullを返します、はい。しかし、それはまた警告を出力します。それにアクセスする前に$ desired_value [$ first_key]が存在することを確認する必要があります。存在しない場合は、$ desired_valueを明示的にnullに設定してループを解除することができます。ループの後、新しいキーを配列に追加することができます。
追加された 著者 Jason Burbage,
申し訳ありませんが、警告ではなく、PHPの通知です。 PHPの設定によっては表示されない可能性がありますが、チェックするのがベストプラクティスです。
追加された 著者 Jason Burbage,
PHP - 日本のコミュニティ [ja]
PHP - 日本のコミュニティ [ja]
4 参加者の

このグループではPHPについて話します。 パートナー:kotaeta.com