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

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

新規登録して質問してみよう
ただいま回答率
85.35%
PHP

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

Q&A

解決済

3回答

274閲覧

PHPで区切り文字構造のテキストからツリー構造配列を作成したい

shizimikai

総合スコア5

PHP

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

0グッド

0クリップ

投稿2020/02/10 07:24

####前提・実現したいこと
PHP5.2.9
以下のような区切り文字テキストを、ツリー構造配列に変換したいです。

1 1.1 1.1.1 1.1.2 1.2 1.3 1.12 1.12.1

期待する結果

php

1$array = array( 2 1 => array( 3 'dat' => '1', 4 1 => array( 5 'dat' => '1.1', 6 1 => array( 7 'dat' => '1.1.1', 8 ), 9 2 => array( 10 'dat' => '1.1.2', 11 ), 12 ), 13 2 => array( 14 'dat' => '1.2', 15 ), 16 3 => array( 17 'dat' => '1.3', 18 ), 19 12 => array( 20 'dat' => '1.12', 21 1 => array( 22 dat => '1.12.1', 23 ), 24 ), 25 ), 26);

####試したこと
explodeにて文字列を配列に分割したところまでは良いと思うのですが、そこから先で詰まっております。

php

1explode('.',$text); 2Array 3( 4 [0] => 1 5) 6Array 7( 8 [0] => 1 9 [1] => 1 10) 11Array 12( 13 [0] => 1 14 [1] => 1 15 [2] => 1 16) 17Array 18( 19 [0] => 1 20 [1] => 1 21 [2] => 2 22) 23...

アドバイスをいただければと思います。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2020/02/10 08:12

datというキーと、datに紐付いた数字からもってきたキーを 並行的にもつのはデータ構造としてはいまいちでは?
shizimikai

2020/02/10 08:22

すいません、書き方がいまいちでした。 元のデータはCSVで、この区切り文字の後ろにデータが連なっています。 そのデータを配列内に持ちたいために、datというダミーキーとダミーデータを挿入しました。 1,aa,bb,cc, ... 1.1,aa,bb,cc, ... 1.1.1,aa,bb,cc, ... 1.1.2,aa,bb,cc, ... ...
yambejp

2020/02/10 08:24

JSON形式で処理してはいかが?
m.ts10806

2020/02/10 09:11

>PHP5.2.9 このバージョンしか使えないのであればアドバイスは得られにくいのでは。
退会済みユーザー

退会済みユーザー

2020/02/10 11:49

とりあえず eolのミドルウェアつかうならそれなりの理由を書かないと自己責任の問題があるので放置プレイになりやすい
shizimikai

2020/02/11 23:35

皆さんの意見を参考に早急に開発バージョンを上げるよう検討したいと思います。
guest

回答3

0

Laravelが提供しているヘルパー関数のArr::setがまさにそのようなものです。

たとえば

php

1Arr::set($x, '1.2.3', 'a');

とするとこれは

php

1$x[1][2][3] = 'a';

と同じような動作をします。

この関数のソースを参考にすると良いでしょう。特に依存関係はなく1つの関数で完結しています。

php

1 /** 2 * Set an array item to a given value using "dot" notation. 3 * 4 * If no key is given to the method, the entire array will be replaced. 5 * 6 * @param array $array 7 * @param string $key 8 * @param mixed $value 9 * @return array 10 */ 11 public static function set(&$array, $key, $value) 12 { 13 if (is_null($key)) { 14 return $array = $value; 15 } 16 17 $keys = explode('.', $key); 18 19 while (count($keys) > 1) { 20 $key = array_shift($keys); 21 22 // If the key doesn't exist at this depth, we will just create an empty array 23 // to hold the next value, allowing us to create the arrays to hold final 24 // values at the correct depth. Then we'll keep digging into the array. 25 if (! isset($array[$key]) || ! is_array($array[$key])) { 26 $array[$key] = []; 27 } 28 29 $array = &$array[$key]; 30 } 31 32 $array[array_shift($keys)] = $value; 33 34 return $array; 35 }

投稿2020/02/10 10:52

crhg

総合スコア1177

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

こんな感じでいかがでしょう? (PHP 7.3.11 で試しました。)

php

1<?php 2 3$arr = [ 4 '1,a', 5 '1.1,b', 6 '1.1.1,c', 7 '1.1.2,d', 8 '1.2,e', 9 '1.3,f', 10 '1.12,g', 11 '1.12.1,h', 12]; 13 14$result = tree($arr); 15print_r($result); 16 17function tree($arr) { 18 $result = []; 19 foreach ($arr as $str) { 20 $dat = explode(',', $str); 21 $node = &$result; 22 foreach (explode('.', $dat[0]) as $d) { 23 $d = intval($d); 24 if (!isset($node[$d])) { 25 $node[$d] = []; 26 } 27 $node = &$node[$d]; 28 } 29 $node['dat'] = $dat[0]; // , の後ろも必要なら [0] を削除。 30 } 31 return $result; 32}

実行結果

Array ( [1] => Array ( [dat] => 1 [1] => Array ( [dat] => 1.1 [1] => Array ( [dat] => 1.1.1 ) [2] => Array ( [dat] => 1.1.2 ) ) [2] => Array ( [dat] => 1.2 ) [3] => Array ( [dat] => 1.3 ) [12] => Array ( [dat] => 1.12 [1] => Array ( [dat] => 1.12.1 ) ) ) )

投稿2020/02/10 10:46

hoshi-takanori

総合スコア7901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shizimikai

2020/02/11 23:36

リファレンス渡しというものの存在を知りませんでした。 ありがとうございます。
guest

0

回答ではないです

最終形が

1,aa,bb,cc, ... 1.1,aa,bb,cc, ... 1.1.1,aa,bb,cc, ... 1.1.2,aa,bb,cc, ...
[1] => "aa,bb,cc, ..." [1][1] => "aa,bb,cc, ..." [1][1][1] => "aa,bb,cc, ..." [1][1][2] => "aa,bb,cc, ..."

のような構造だとすると、配列では実現できません。
最終形を再整理してみては?

投稿2020/02/12 00:15

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問