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

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

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

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

PHP

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

配列

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

Q&A

解決済

1回答

842閲覧

PHP で二次元配列に含まれる特定のキーが連番にならないようにする時の処理と、その名称を教えてほしい

m1y474

総合スコア23

多次元配列

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

PHP

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

配列

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

0グッド

0クリップ

投稿2021/12/24 08:08

前提・実現したいこと

PHPで二次元配列に含まれる特定のキーが連番にならないように整形したいです。

特定のキーが以下のように並んでいる場合は、
[A, B, A, B, B, B, C, D, D, E, F, F, A, B, B, D, G]

下記のように同じ文字列が連続しないように整形したいです。
(ただし、残っている文字列が全て同じ場合は連続しても良いです。)
[A, B, C, D, E, F, G, A, B, D, F, A, B, D, B, B, B]

二次元配列を一次元配列にすれば文字列が連続しないように整形できるのですが、 // 二次元配列として入れ直す の部分で再度 foreach を実施しています。
なるべくコードを簡潔に済ませるために $sorting クロージャ中で済ませたいです。
このような処理をする場合は二次元配列のままでは難しいのでしょうか?

また、こういった数字が連続しないようにする処理の名前があれば教えていただきたいです。

該当のソースコード(試したこと)

php

1<?php 2 3$values = [ 4 [ 5 'id' => '2', 6 'category_id' => 'A', 7 ], [ 8 'id' => '30', 9 'category_id' => 'A', 10 ], [ 11 'id' => '12', 12 'category_id' => 'B', 13 ], [ 14 'id' => '8', 15 'category_id' => 'B', 16 ], [ 17 'id' => '10', 18 'category_id' => 'C', 19 ], [ 20 'id' => '329', 21 'category_id' => 'D', 22 ], [ 23 'id' => '89', 24 'category_id' => 'E', 25 ], [ 26 'id' => '79', 27 'category_id' => 'E', 28 ], [ 29 'id' => '58', 30 'category_id' => 'A', 31 ], [ 32 'id' => '219', 33 'category_id' => 'B', 34 ], [ 35 'id' => '44', 36 'category_id' => 'B', 37 ], [ 38 'id' => '3219', 39 'category_id' => 'B', 40 ], [ 41 'id' => '231', 42 'category_id' => 'B', 43 ], [ 44 'id' => '43210', 45 'category_id' => 'F', 46 ] 47]; 48 49// 一次元配列にする 50$categoryIds = array_column($values, 'category_id'); 51// 処理済みの category_id を格納する変数 52$sorted = []; 53// 残っている category_id が一種類のみかどうかを判定する変数 54$hasOneSubject = false; 55 56$sorting = function ($categoryIds) use (&$sorting, &$sorted, &$hasOneCategory) { 57 // 重複を削除した category_id 58 $uniqueCategory = array_unique($categoryIds); 59 // 使用済みの category_id を格納しておく変数 60 $used = []; 61 62 foreach ($categoryIds as $index => $id) { 63 // 処理済みの配列から一番最後を取得 64 $lastKey = array_key_last($sorted); 65 // 残りの category_id が一種類しかない場合を除き、直近の配列が同じ場合はskip。 66 if (isset($sorted[$lastKey]) && $sorted[$lastKey] === $id && !$hasOneCategory) { 67 continue; 68 } 69 // category_id を全種類使い切った場合は使用済みをリセットする 70 if (count($uniqueCategory) === count(array_unique($used))) { 71 $used = []; 72 } 73 // 既に同一の category_id を処理済みの場合はskip 74 if (in_array($id, $used)) { 75 continue; 76 } 77 $sorted[$index] = $id; 78 $used[] = $id; 79 } 80 81 // 残りの配列 82 $diff = array_diff_assoc($categoryIds, $sorted); 83 // 残りの配列が一種類かどうか 84 $hasOneCategory = count(array_unique($diff)) === 1; 85 86 // 残っている配列がある場合は再帰処理を実施 87 if (count($diff) > 0) { 88 return $sorting($diff); 89 } 90 91 return $sorted; 92}; 93 94$sortedValues = []; 95// 二次元配列次元配列として入れ直す 96foreach ($sorting($categoryIds) as $key => $value) { 97 $sortedValues[$key] = $values[$key]; 98} 99var_dump($sortedValues);

下記にも転記しました。
https://3v4l.org/5DREG

補足情報(FW/ツールのバージョンなど)

PHP 7.4.25


※[発生している問題・エラーメッセージ], は特になく、[試したこと]は[該当のソースコード]に記載しましたので省略しました。
他にも提示すべき情報がございましたらお手数ですがご指示ください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

PHP

1$a=["A","B","A","B","B","B","C","D","D","E","F","F","A","B","B","D","G"]; 2$b=[]; 3$c=null; 4while(count($a)>0){ 5// shuffle($a); 6 $a=array_merge(array_filter($a,function($x) use($c){ 7 return $x!=$c; 8 }),array_filter($a,function($x) use($c){ 9 return $x==$c; 10 })); 11 $b[]=($c=array_splice($a,0,1)[0]); 12} 13json_encode($b); 14/* 15 shuffleしなければ 16 ["A","B","C","D","E","F","G","A","B","D","F","A","B","D","B","B","B"] 17 が返る 18*/

二次配列の場合

二次配列でも考え方は同じ

PHP

1<?PHP 2$a=[ 3 ['id' => '2' ,'category_id' => 'A',], 4 ['id' => '30' ,'category_id' => 'A',], 5 ['id' => '12' ,'category_id' => 'B',], 6 ['id' => '8' ,'category_id' => 'B',], 7 ['id' => '10' ,'category_id' => 'C',], 8 ['id' => '329' ,'category_id' => 'D',], 9 ['id' => '89' ,'category_id' => 'E',], 10 ['id' => '79' ,'category_id' => 'E',], 11 ['id' => '58' ,'category_id' => 'A',], 12 ['id' => '219' ,'category_id' => 'B',], 13 ['id' => '44' ,'category_id' => 'B',], 14 ['id' => '3219' ,'category_id' => 'B',], 15 ['id' => '231' ,'category_id' => 'B',], 16 ['id' => '43210','category_id' => 'F',], 17 ]; 18$b=[]; 19$c=[]; 20while(count($a)>0){ 21 //shuffle($a); 22 $category=isset($c["category_id"])?$c["category_id"]:null; 23 $a=array_merge(array_filter($a,function($x) use($category){ 24 return $x["category_id"]!=$category; 25 }),array_filter($a,function($x) use($category){ 26 return $x["category_id"]==$category; 27 })); 28 $b[]=($c=array_splice($a,0,1)[0]); 29} 30print json_encode($b);

投稿2021/12/24 10:41

編集2021/12/24 11:49
yambejp

総合スコア114572

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

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

yambejp

2021/12/24 10:42

名称は知りません
m1y474

2021/12/24 15:35

ありがとうございます! [二次配列の場合]でいただいたコードがまさにやりたかったことです! こんなに短くかけるなんて知りませんでした。てっきりこのような処理の場合は再帰処理は必須だと思いこんでいました。大変勉強になります???? 名称についてご存じないとのことも承知しました。 コードをご教授いただけただけでもありがたいです。 ありがとうございました????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問