質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.62%

  • PHP

    19892questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

php 多次元配列の分割

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 221

holic

score 83

 前提・実現したいこと

多次元配列を一定の間隔に分割したい。
下記のようにする関数設定はありますでしょうか、もしくは自作されている方いらっしゃいますでしょうか。

 該当のソースコード

//多次元配列
$list_pre = array(
  array(1,2,3,4,5,6),
  array(7,8,9,10,11,12),
  array(13,14,15,16,17,18),
  array(19,20,21,22,23,24),
);


//条件(横2、縦2に分割)
//↓並び替え


$list_after = array(
  array(
    array(1,2),
    array(7,8),
  ),
  array(
    array(3,4),
    array(9,10),
  ),
  array(
    array(5,6),
    array(11,12),
  ),
);
//多次元配列
$list_pre = array(
  array(1,2,3,4,5,6),
  array(7,8,9,10,11,12),
  array(13,14,15,16,17,18),
  array(19,20,21,22,23,24),
);


//条件(横3、縦2に分割)
//↓並び替え


$list_after = array(
  array(
    array(1,2,3),
    array(7,8,9),
  ),
  array(
    array(4,5,6),
    array(10,11,12),
  ),
  array(
    array(13,14,15),
    array(19,20,21),
  ),
  array(
    array(16,17,18),
    array(22,23,24),
  ),
);

●試してみたこと

試した参考ページ
http://php.net/manual/ja/function.array-chunk.php

array_chunkという関数を発見したのですが、多次元配列に対応をどうすれば良いのか悩み、断念しました。

phpまたは配列操作に詳しい方がいらっしゃいましたら、ご教示願います。
以上

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2018/05/14 06:59

    このままだとやりたいことだけを記載した丸投げ質問なのでご自身でやってみたこと、調べたことを記載してください。

    キャンセル

  • holic

    2018/05/14 07:42 編集

    mts10806様 ある配列を分割する関数としてarray_chunk($list_pre[0], 2) を発見して試してみました。しかしながら、多次元に対しての「2」の指定が困難であると頭を悩ませました。多次元に対してはこの関数は使えないかなと思いまして、悩んでいたところです

    キャンセル

  • mts10806

    2018/05/14 07:44

    参考にした記事なども含めて質問本文に追加していただけますか?

    キャンセル

回答 1

checkベストアンサー

+1

細かい仕様よくわからんけど、とりあえず、書いた。

<?php

function validate_array($array, $columns, $rows)
{
    if(!is_array($array))    { throw new Exception("第一引数が配列ではありません。"); }

    $elements_count = -1;
    $count          = count($array);

    if($count % $rows !== 0)
    {
        throw new Exception("指定された行数は配列行数に対してマッチしません。");
    }

    for($i = 0; $i < $count; $i++)
    {
        if(!is_array($array[$i]))
        {
            throw new Exception("配列の{$i}番目の要素が配列ではありません。");
        }

        if($elements_count < 0)
        {
            if(count($array[$i]) % $columns !== 0)
            {
                throw new Exception("指定された分割数は配列の要素数に対してマッチしません。");
            }

            $elements_count = count($array[$i]);
            continue;
        }

        if(count($array[$i]) !== $elements_count)
        {
            throw new Exception("配列の{$i}番目の要素数が不正です。多次元配列ではなくジャグ配列です。");
        }
    }

    return;
}

function array_devide($array, $columns, $rows)
{
    // 配列のヴァリデーション
    validate_array($array, $columns, $rows);

    $list_after = array();


    for($r = 0; $r <count($array); $r += $rows)
    {
        for($c = 0; $c < count($array[0]); $c += $columns)
        {
            $temp = array();

            for($i = 0; $i < $rows; $i++)
            {
                if(!isset($array[$r + $i])){ break; }
                $temp[] = array_slice($array[$r + $i] , $c, $columns);
            }

            $list_after[] = $temp;
        }
    }

    return $list_after;
}

//多次元配列
$list_pre = array(
  array(1,2,3,4,5,6),
  array(7,8,9,10,11,12),
  array(13,14,15,16,17,18),
  array(19,20,21,22,23,24),
);

try
{
    $list_after = array_devide($list_pre, 3, 4);
}
catch (Exception $ex)
{
    echo $ex->getMessage();
    die;
}

print_r($list_after);

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/15 18:33

    lucker様
    バリデーションまで書いていただきありがとうございます。
    ちょっと解読に時間がかかってますのでもうすこしお時間を下さい。

    キャンセル

  • 2018/05/18 20:13 編集

    lucker様

    いろいろと整理しましたが、どうしてもわからないところがございます。
    しかもかなり初歩的なところです。

    最終生成生物が $list_afterが構築されていっているところはわかりました。
    下の記述ですが、
    ''$list_after[] = $temp;''
    なぜこれで、$list_afterに追加されていっているのかが本当に理解できずに悩みました。
    (この記述だとfor文の度に打ち消されてしまうのではないかと考えてしまいました)
    array_drop($list_after,$temp);
    みたいな感じで作っていくのかなと考えていたのですが、
    すいません、その部分だけ詳細説明をお願いできませんでしょうか。
    お手数とは思いますがよろしくお願いいたします。

    キャンセル

  • 2018/05/18 20:18

    んと、
    $list_after = $temp;
    だと、$list_afterを$tempで上書きですけど、

    $list_after[] = $temp;
    だと、配列$list_afterの末尾に要素$tempを追加するという意味になって
    array_push($list_after, $temp);
    と、ほぼ同じ意味になります。

    キャンセル

  • 2018/05/18 20:24

    今私もアパッチ環境で試してみましたが、そうだったんですね。


    $list_after[] = $temp;
    だと、配列$list_afterの末尾に要素$tempを追加するという意味になって
    array_push($list_after, $temp);

    すいません、こんな初歩的なことも知りませんでした。長い時間お付き合いありがとうございます。
    大変に勉強になる解答です。
    今後ともよろしくお願いいたします。

    キャンセル

  • 2018/05/18 20:25

    うぃうぃ

    キャンセル

  • 2018/05/18 21:14

    その後いろいろと思考させていただきましたが、ほんとに勉強になる「解答」で合ったと思います。
    すいませんが、フォローもさせてくださいませ!!

    キャンセル

  • 2018/05/18 21:16

    うぃうぃ

    キャンセル

  • 2018/05/21 01:55 編集

    もしお時間あればご回答いただけましたらうれしいのですが。

    lucker様の回答を一通り、目を通して、もう一度自分で記述してみました。
    すると下記のように書いてしまったのですが、これがうまくいかない理由がよくわからなかったです。
    なぜこの方法だとうまくいかないのかわかりますでしょうか。

    $temp[] = array_slice($array[$r + $i] , $c, $columns);

    $temp[] = array_splice($array[$r + $i] , 0, $columns);

    array_spliceを使うことにより、元になる配列値も変更になっていきます。
    ですので、切り取り指定の初期値は常に「0」になり、わかりやすいかなと考えてこのように書きました。
    しかし結果はうまくいってないです。
    何故なのでしょうか。

    キャンセル

  • 2018/05/21 02:25

    自己解決しました。
    array_spliceをすると。
    for($c = 0; $c < count($array[0]); $c += $columns)
    の$array[0]の数値も小さくなってしまうことが原因でした。
    ですので

    $countColumn = count($array[0]);
    for($c = 0; $c < $countColumn; $c += $columns)
    とすることでspliceでも可能となりました。
    ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • PHP

    19892questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。