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

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

新規登録して質問してみよう
ただいま回答率
85.48%
多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

PHP

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

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

4回答

1695閲覧

php 多次元配列のグループ化、振り分け方法

tyutyu

総合スコア16

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

PHP

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

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2017/09/11 13:10

編集2017/09/11 14:18

以下の振り分け方法で、以下のような多重の配列を$result にするための、
アルゴリズムわかる方いませんか?

URLで以下参考にしたが 非常におしいです。多次元なんとかならないでしょうか。
PHP:連想配列をキーでグループ化
array_columnの多次元配列

$A=array( 'type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>No1001, 'type' =>1, 'value'=>200, 'cnt'=>6, 'no'=>No1002, 'type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>No1003, 'type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>No1004, 'type' =>2, 'value'=>10, 'cnt'=>10, 'no'=>No1005, 'type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>No1006, 'type' =>2, 'value'=>10, 'cnt'=>10, 'no'=>No1007, 'type' =>2, 'value'=>11, 'cnt'=>5, 'no'=>No1008, 'type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>No1009, 'type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>No1010, 'type' =>2, 'value'=>10, 'cnt'=>5, 'no'=>No1011, : : ); ↓ $result = array( 'type' =>'1' , 'value'=> 200, 'cnt'=>5 'nolist'=>'No1001,No1006,No1010,', 'type' =>'1' , 'value'=> 200, 'cnt'=>6 'nolist'=>'No1002,', 'type' =>'1' , 'value'=> 201, 'cnt'=>5 'nolist'=>'No1003,No1004,No1009', 'type' =>'2' , 'value'=> 10, 'cnt'=>10 'nolist'=>'No1005,No1007,', 'type' =>'2' , 'value'=> 11, 'cnt'=>5 'nolist'=>'No1008,', 'type' =>'2' , 'value'=> 10, 'cnt'=>5 'nolist'=>'No1011,', );

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

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

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

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

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

kei344

2017/09/11 13:11

ご自身で試されたコードを質問文に追記し、「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを具体的に追記されたほうが回答が望めると思います。
退会済みユーザー

退会済みユーザー

2017/09/11 15:43

自分で試してないでしょ。丸投げは NG ですよ。
guest

回答4

0

データがおかしい
No1011はNo1005,No1007とcnt値がちがう

PHP

1$a=[ 2 ['type' =>1, 'value'=>200,'cnt'=>5, 'no'=>'No1001'], 3 ['type' =>1, 'value'=>200,'cnt'=>6, 'no'=>'No1002'], 4 ['type' =>1, 'value'=>201,'cnt'=>5, 'no'=>'No1003'], 5 ['type' =>1, 'value'=>201,'cnt'=>5, 'no'=>'No1004'], 6 ['type' =>2, 'value'=>10, 'cnt'=>10,'no'=>'No1005'], 7 ['type' =>1, 'value'=>200,'cnt'=>5, 'no'=>'No1006'], 8 ['type' =>2, 'value'=>10, 'cnt'=>10,'no'=>'No1007'], 9 ['type' =>2, 'value'=>11, 'cnt'=>5, 'no'=>'No1008'], 10 ['type' =>1, 'value'=>201,'cnt'=>5, 'no'=>'No1009'], 11 ['type' =>1, 'value'=>200,'cnt'=>5, 'no'=>'No1010'], 12 ['type' =>2, 'value'=>10, 'cnt'=>5, 'no'=>'No1011'], 13]; 14$b=[]; 15 16foreach($a as $arr){ 17 $c=array_filter($b,function($i) use($arr){ 18 return $i['type']==$arr['type'] and $i['value']==$arr['value'] and $i['cnt']==$arr['cnt']; 19 }); 20 if(count($c)==0){ 21 $arr["nolist"]=$arr["no"].","; 22 unset($arr["no"]); 23 array_push($b,$arr); 24 }else{ 25 $b[array_keys($c)[0]]["nolist"].=$arr["no"].","; 26 } 27} 28print_r($b);

投稿2017/09/11 14:14

yambejp

総合スコア114784

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

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

tyutyu

2017/09/11 14:19

失礼しました。No1011 訂正しました。
退会済みユーザー

退会済みユーザー

2017/09/12 06:04

これ、なんで評価下がってるんだろ。。。 気になりますね^^;
yambejp

2017/09/12 06:16

最近低評価も慣れてきましたが 今日ちょうどオフ会があるらしいので 低評価システムについてきいてみようかなぁと・・・
退会済みユーザー

退会済みユーザー

2017/09/12 06:35

低評価入れるならコメント入れてくれるとイイんですけどねぇ。 動かしたらわかるかもと思って動かしてみたけど、やっぱりわからんw
guest

0

この仕様だと、無理です。

追記
課題として面白そうだったので、勝手に仕様を決めてスクリプト書いてみました。

php

1<?php 2 3$a = [ 4 ['type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>'No1001'], 5 ['type' =>1, 'value'=>200, 'cnt'=>6, 'no'=>'No1002'], 6 ['type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>'No1003'], 7 ['type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>'No1004'], 8 ['type' =>2, 'value'=>10, 'cnt'=>10, 'no'=>'No1005'], 9 ['type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>'No1006'], 10 ['type' =>2, 'value'=>10, 'cnt'=>10, 'no'=>'No1007'], 11 ['type' =>2, 'value'=>11, 'cnt'=>5, 'no'=>'No1008'], 12 ['type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>'No1009'], 13 ['type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>'No1010'], 14 ['type' =>2, 'value'=>10, 'cnt'=>5, 'no'=>'No1011'], 15 ]; 16 17foreach ($a as $val) { 18 $type = $val['type']; 19 $value = $val['value']; 20 $cnt = $val['cnt']; 21 $no = $val['no']; 22 if(isset($tmp[$type.'_'.$value.'_'.$cnt])){ 23 $tmp[$type.'_'.$value.'_'.$cnt] = $tmp[$type.'_'.$value.'_'.$cnt].', '.$no; 24 }else{ 25 $tmp[$type.'_'.$value.'_'.$cnt] = $no; 26 } 27} 28foreach ($tmp as $key => $nolist) { 29 list($type, $value, $cnt) = explode('_', $key); 30 $result[] = ['type' => $type, 'value'=> (int)$value, 'cnt'=> (int)$cnt, 'nolist'=> $nolist]; 31} 32var_dump($result);

更に追記
解決にするのはイイんですけど、せめて質問の配列、修正しませんか^^;
$A は Notice も出るし、$result はそもそも配列として成立しません。
正解も回答者が記述しているのですから。。。

php

1var_dump($A); 2array(4) { 3 ["type"]=> 4 int(2) 5 ["value"]=> 6 int(10) 7 ["cnt"]=> 8 int(5) 9 ["no"]=> 10 string(6) "No1011" 11}

投稿2017/09/11 13:31

編集2017/09/12 02:35
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2017/09/11 15:17

低評価入れている人、質問の var_dump($A) 確認してみるとイイですよ。
guest

0

ベストアンサー

他の方と大差はないですが、ソートを考慮してみました。

PHP

1$a = [ 2 ['type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>'No1001'], 3 ['type' =>1, 'value'=>200, 'cnt'=>6, 'no'=>'No1002'], 4 ['type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>'No1003'], 5 ['type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>'No1004'], 6 ['type' =>2, 'value'=>10, 'cnt'=>10, 'no'=>'No1005'], 7 ['type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>'No1006'], 8 ['type' =>2, 'value'=>10, 'cnt'=>10, 'no'=>'No1007'], 9 ['type' =>2, 'value'=>11, 'cnt'=>5, 'no'=>'No1008'], 10 ['type' =>1, 'value'=>201, 'cnt'=>5, 'no'=>'No1009'], 11 ['type' =>1, 'value'=>200, 'cnt'=>5, 'no'=>'No1010'], 12 ['type' =>2, 'value'=>10, 'cnt'=>5, 'no'=>'No1011'], 13 ]; 14 15$tmp = $ret = array(); 16$fmt = '%02d_%04d_%03d'; // 大きい数字があってもいいように1桁余分 17foreach ($a as $val) { 18 $tmp[ sprintf($fmt, $val['type'], $val['value'], $val['cnt'])][] = $val['no']; 19} 20ksort($tmp); 21 22foreach ($tmp as $k => $no) { 23 $k2 = array_map('intval', explode('_', $k)); 24 sort($no); 25 $ret[] = array('type' => $k2[0], 'value' => $k2[1], 'cnt' => $k2[2], 'nolist'=> implode(',', $no)); 26} 27print_r($ret);

投稿2017/09/12 00:22

n884

総合スコア100

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

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

0

ロジックを下記のようにします。

  1. $Atype, value, cnt値のが同値な要素を探す
    → 適当に区切り文字を入れてtype:value:cntのフォーマットで文字列結合してしまいます。
    → 探しやすいようにNoXXX => type:value:cntのようにリフォーマットします。
    → array_search() だと1つしか探せないので、array_keys()を使用します。

  2. 上記の同値要素のnoをカンマ区切りで保存
    array_keys()の結果はヒットした要素のキーの配列なのでimplode()で結合します

  3. 上記カンマ区切りの連想配列のキーはnolistとする

array_unique()して重複を取り除いたユニークキーで連想配列を検索します。

php

1$A = [ 2 ['type' => 1, 'value' => 200, 'cnt' => 5, 'no' => 'No1001',], 3 ['type' => 1, 'value' => 200, 'cnt' => 6, 'no' => 'No1002',], 4 ['type' => 1, 'value' => 201, 'cnt' => 5, 'no' => 'No1003',], 5 ['type' => 1, 'value' => 201, 'cnt' => 5, 'no' => 'No1004',], 6 ['type' => 2, 'value' => 10, 'cnt' => 10, 'no' => 'No1005',], 7 ['type' => 1, 'value' => 200, 'cnt' => 5, 'no' => 'No1006',], 8 ['type' => 2, 'value' => 10, 'cnt' => 10, 'no' => 'No1007',], 9 ['type' => 2, 'value' => 11, 'cnt' => 5, 'no' => 'No1008',], 10 ['type' => 1, 'value' => 201, 'cnt' => 5, 'no' => 'No1009',], 11 ['type' => 1, 'value' => 200, 'cnt' => 5, 'no' => 'No1010',], 12 ['type' => 2, 'value' => 10, 'cnt' => 5, 'no' => 'No1011',], 13]; 14 15$result = []; 16$array = []; 17 18foreach ($A as $row) { 19 $array[$row['no']] = $row['type'].':'.$row['value'].':'.$row['cnt']; 20} 21 22foreach (array_unique($array) as $search) { 23 list($type, $value, $cnt) = explode(':', $search); 24 $result[] = [ 25 'type' => $type, 26 'value' => $value, 27 'cnt' => $cnt, 28 'nolist' => implode(',', array_keys($array, $search)), 29 ]; 30} 31 32echo '<pre>'; 33print_r($result); 34echo '</pre>';

投稿2017/09/11 18:11

編集2017/09/11 18:21
Tomak

総合スコア1652

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問