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

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

ただいまの
回答率

90.48%

  • PHP

    20877questions

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

  • 配列

    534questions

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

  • アルゴリズム

    421questions

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

  • 多次元配列

    36questions

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

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

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,174

tyutyu

score 7

以下の振り分け方法で、以下のような多重の配列を$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,',
);
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • kei344

    2017/09/11 22:11

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

    キャンセル

  • te2ji

    2017/09/12 00:43

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

    キャンセル

回答 4

checkベストアンサー

+1

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

$a = [
    ['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'],
    ];

$tmp = $ret = array();
$fmt = '%02d_%04d_%03d';  // 大きい数字があってもいいように1桁余分
foreach ($a as $val) {
    $tmp[ sprintf($fmt, $val['type'], $val['value'], $val['cnt'])][] = $val['no'];
}
ksort($tmp);

foreach ($tmp as $k => $no) {
    $k2 = array_map('intval', explode('_', $k));
    sort($no);
    $ret[] = array('type' => $k2[0], 'value' => $k2[1], 'cnt' => $k2[2], 'nolist'=> implode(',', $no));
}
print_r($ret);

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

+1

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

$a=[
  ['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'],
];
$b=[];

foreach($a as $arr){
  $c=array_filter($b,function($i) use($arr){
    return $i['type']==$arr['type'] and $i['value']==$arr['value'] and $i['cnt']==$arr['cnt'];
  });
  if(count($c)==0){
    $arr["nolist"]=$arr["no"].",";
    unset($arr["no"]);
    array_push($b,$arr);
  }else{
    $b[array_keys($c)[0]]["nolist"].=$arr["no"].",";
  }
}
print_r($b);

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/09/11 23:19

    失礼しました。No1011 訂正しました。

    キャンセル

  • 2017/09/12 15:04

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

    キャンセル

  • 2017/09/12 15:16

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

    キャンセル

  • 2017/09/12 15:35

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

    キャンセル

+1

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

  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()して重複を取り除いたユニークキーで連想配列を検索します。

$A = [
    ['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  = [];

foreach ($A as $row) {
    $array[$row['no']] = $row['type'].':'.$row['value'].':'.$row['cnt'];
}

foreach (array_unique($array) as $search) {
    list($type, $value, $cnt) = explode(':', $search);
    $result[] = [
        'type'   => $type,
        'value'  => $value,
        'cnt'    => $cnt,
        'nolist' => implode(',', array_keys($array, $search)),
    ];
}

echo '<pre>';
print_r($result);
echo '</pre>';

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

-3

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

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

<?php

$a = [
    ['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'],
    ];

foreach ($a as $val) {
    $type = $val['type'];
    $value = $val['value'];
    $cnt = $val['cnt'];
    $no = $val['no'];
    if(isset($tmp[$type.'_'.$value.'_'.$cnt])){
        $tmp[$type.'_'.$value.'_'.$cnt] = $tmp[$type.'_'.$value.'_'.$cnt].', '.$no;
    }else{
        $tmp[$type.'_'.$value.'_'.$cnt] = $no;
    }
}
foreach ($tmp as $key => $nolist) {
    list($type, $value, $cnt) = explode('_', $key);
    $result[] = ['type' => $type, 'value'=> (int)$value, 'cnt'=> (int)$cnt, 'nolist'=> $nolist];
}
var_dump($result);

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

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

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/09/12 00:17

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

    キャンセル

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

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

関連した質問

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

  • PHP

    20877questions

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

  • 配列

    534questions

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

  • アルゴリズム

    421questions

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

  • 多次元配列

    36questions

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