Help us understand the problem. What is going on with this article?

45歳から始めるプログラミング PHP編 No1 多次元配列を1次元配列に変換する関数を書け!(再帰処理で)

More than 1 year has passed since last update.

study-php 2018-04-29 22-40-55.png

こんにちは。nouphetです。

私はインフラエンジニアなのでbash以外のコードはほぼ書いてなかったのですが、最近プログラムを書きたくなってPHPの勉強をはじめました。

最初はUdemyで基礎知識を学んでいたのですが、同僚の @reoring@suin が課題を出してくれて挑戦したので、経過の記録として公開します。

ちなみにUdemyはオンラインで学ぶことができるサービスで普段は1コース数千円〜数万円するのですが、たまにキャンペーンをやっていて千円台で購入することができるタイミングがあるので、そこを狙うと割りとお金を掛けずに学べるし早いので良いです。

ちなみに私はこの2コースを学びました。
* PHP初級プログラミング講座 初級 その1| Udemy ←キャンペーン価格で 1,700円でした。
* PHP初級プログラミング講座 初級 その2 | Udemy ←キャンペーン価格で 1,500円でした。

そして同僚が出してくれた課題がこちら。

多次元配列を1次元配列に変換する関数を書け!(再帰処理で)

<?php

$a = [1, [2, [3, [4, [5]]]]];
$b = [1, 2, 3, 4, 5];

function f($a) {
    // ここを実装してね
}

$c = f($a);

if ($b === $c) {
    echo "OK";
} else {
    echo "NG";
}

この課題を解決することで
* 配列の扱い方
* 再帰関数の書き方
を学ぶが出来ます。

実装してみた第1弾

実装はいろいろな方法で出来るようですが、お題として「再帰処理で」という条件が含まれていたのでそれなりに調べ悩みながら実装してみました。

n_array2.php
<?php

$a = [1, [2, [3, [4, [5]]]]];
$b = [1, 2, 3, 4, 5];
// 値が数値だとわかりずらかったので検証中は英文字に置き換え
// $a = ['a', ['b', ['c', ['d', ['e']]]]];
// $b = ['a', 'b', 'c', 'd', 'e'];
// $a = [1, "aaa"=>"AAA", [2, [3, [4, [5]]]]];
// $b = [1, "AAA", 2, 3, 4, 5];

function f($a) {
    // ここを実装してね
    global $c;
    foreach ($a as $key => $value) {

        if (is_array($value)) {
            $a = $a[$key];
            f($a);
        } else {
            $c[] = $value;
        }
    }
    // echo 'var_dump($c)' . "\n";
    // var_dump($c);
    // echo "\n";
    return $c;
    unset($c);
}

$c = f($a);

if ($b === $c) {
    echo "OK\n";
} else {
    echo "NG\n";
}

再帰関数ということで関数の中で同じ関数を呼び出すということはわかった。しかしforeachの中から再帰的に処理した結果を取り出すということがうまくできなかったので、globalを使って実装してみた。処理結果としてはOKだったが、なんとなくglobalは使うと大きなプログラムの中で使う時にまずいんじゃないかなーとは思っていると、やはりその通りで「今度はglobal使わずにやってみて」とコメントをもらったので、再び挑戦。

実装してみた第2弾

ファイル番号が6になっていますが、試行錯誤の結果増えていきましたw
コードがごちゃごちゃしてきて混乱してきたらすっきり新しく書き始めるのが良さそうです :grinning:

n_array6.php
<?php

$a = [1, [2, [3, [4, [5]]]]];
$b = [1, 2, 3, 4, 5];
// $a = ['a', ['b', ['c', ['d', ['e']]]]];
// $b = ['a', 'b', 'c', 'd', 'e'];
// $a = ['a', ['b']];
// $b = ['a', 'b'];
// $a = [1, "aaa"=>"AAA", [2, [3, [4, [5]]]]];
// $b = [1, "AAA", 2, 3, 4, 5];
// $a = [a, ["AAA"], [b, [c, [d, [e]]]]];
// $b = [a, "AAA", b, c, d, e];

// print_r($b);

function f($a) {
    // ここを実装してね
    $ret = array();
    foreach ($a as $key => $value) {
        if(! is_array($value)) {
            // echo 'if value = ';
            // var_dump($value);

            $ret[] = $value;

            // echo 'ret = ';
            // var_dump($ret);
        } else {
            // $a = $value;

            // echo 'else value = ';
            // var_dump($value);
            $ret = array_merge($ret, f($value));
        }
    }
    // echo '===3=== $ret = ';
    // var_dump($ret);
    return $ret;
}

$c = f($a);

// echo '============================' . "\n";
// echo 'var_dump($c)_3' . "\n";
// echo join(',',$c);
// echo "\n";

if ($b === $c) {
    echo "OK\n";
} else {
    echo "NG\n";
}

実行結果

$ php n_array6.php
OK

なんとか処理を実装することができた。
次に再帰関数を使ってフィボナッチ数列を出力する関数を書くというお題をもらったので、次の記事に書きたいと思う。

ちなみにこのシリーズの進捗は YYPHP でもお題の共有や進捗報告をしています。

また、「わかばちゃんと学ぶシリーズ」著者の @llminatoll や他の方ももチャレンジしているので、他の人はどう実装しているのか興味のある方はぜひ覗いてみてください〜!

興味のある方はぜひチャレンジしてみてください!!

出題者からの回答例はこちら

これからチャレンジしようと思っている人は見ないで〜!

YYPHPは毎週やってます

PHPについてワイワイ話したい方は、YYPHPのイベント情報をチェックしてみて下さい。

最近、Slackや [YYPHP - YouTubeライブ]での参加者も多くなってきたので次回募集分からオンライン参加枠も作りました!当日現地に来れない方もオンラインでぜひご参加ください!

ではでは、また!:smiley:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした