前提・実現したいこと
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
※[発生している問題・エラーメッセージ], は特になく、[試したこと]は[該当のソースコード]に記載しましたので省略しました。
他にも提示すべき情報がございましたらお手数ですがご指示ください。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/12/24 10:42
2021/12/24 15:35