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

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

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

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

Q&A

解決済

1回答

244閲覧

PHP 空文字をランキングの最下層にまとめつつ、順位順、かつ、タイム順で並び替えたい

qwe001

総合スコア133

PHP

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

0グッド

0クリップ

投稿2022/10/05 09:06

編集2022/10/06 01:46

やりたいこと

  • 走行記録のCSVを読み込み、通過順位 昇順で、ランキング表示したい
  • ただし、通過順位が空欄の時は、最下位の下にまとめて表示する
    • 1->2->3->4->空欄1->空欄2->... みたいな
  • 通過順位が空欄の時、通過タイム 昇順で並び替えて表示する
    • MySQLで言うところの GROUP BY rank ORDER BY rank ASC, time ASC みたいなことがしたい
    • 通過タイムも空欄の場合がある。通過順位、通過タイムともに空欄なら、一番下に表示する
      • 難しければこれは実装不要です

CSV

csv:data/test.csv

1通過順位,名前,通過タイム,区間順位,区間タイム 21,aaa,12:45*,1,12:45* 33,ccc,13:00*,3,13:00* 42,bbb,12:57*,2,12:57* 54,ddd,13:00*,4,13:00* 6,xxx,15:36*,,15:36* 7,vvv,14:12*,,14:12* 8,yyy,18:05*,,18:05* 9,zzz,,,

現在の実装

現在のループ中の通過順位($row1Rank)と次のループの通過順位($row2Rank)が同一、
または異なる時、通過タイムで比較して、数字の小さいほうを上に表示したいのですが、
どのように実装すれば良いかがわかりません

php

1/** 2 * 値の大小比較を行う 3 * 空文字は一番下にする 4 * 5 * @param {Array} $row1 6 * @param {Array} $row2 7 * @return {Integer} 8 */ 9function compare($row1, $row2) 10{ 11 $row1Rank = $row1[0]; $row2Rank = $row2[0]; 12 $row1Time = $row1[2]; $row2Time = $row2[2]; 13 14 if($row1Rank == $row2Rank) { // 空白や同一文字が連続した時 15 //return 0; 16 17 if($row1Time == $row2Time){ 18 return 0; 19 } 20 else if($row1Time == ""){ 21 return 1; 22 } 23 else if($row2Rank == ""){ 24 return -1; 25 } 26 27 return $row1Time <=> $row2Time; 28 } 29 else if($row1Rank == "") { 30 return 1; 31 } 32 else if($row2Rank == "") { 33 return -1; 34 } 35 36 return $row1Rank <=> $row2Rank; 37} 38 39usort($arr, "compare");

現在の並び順表示

1(aaa)->2(bbb)->3(ccc)->4(ddd)->(xxx)->(vvv)->(yyy)->(zzz) の順で並びます。

json

1[ 2 [ 3 "1", 4 "aaa", 5 "12:45*", 6 "1", 7 "12:45*" 8 ], 9 [ 10 "2", 11 "bbb", 12 "12:57*", 13 "2", 14 "12:57*" 15 ], 16 [ 17 "3", 18 "ccc", 19 "13:00*", 20 "3", 21 "13:00*" 22 ], 23 [ 24 "4", 25 "ddd", 26 "13:00*", 27 "4", 28 "13:00*" 29 ], 30 [ 31 "", 32 "xxx", 33 "15:36*", 34 "", 35 "15:36*" 36 ], 37 [ 38 "", 39 "vvv", 40 "14:12*", 41 "", 42 "14:12*" 43 ], 44 [ 45 "", 46 "yyy", 47 "18:05*", 48 "", 49 "18:05*" 50 ], 51 [ 52 "", 53 "zzz", 54 "", 55 "", 56 "" 57 ] 58]

理想の並び順表示

1(aaa)->2(bbb)->3(ccc)->4(ddd)->(vvv)->(xxx)->(yyy)->(zzz) の順で並んでほしいです
順位順かつ、タイム順で並ばせたいです

json

1[ 2 [ 3 "1", 4 "aaa", 5 "12:45*", 6 "1", 7 "12:45*" 8 ], 9 [ 10 "2", 11 "bbb", 12 "12:57*", 13 "2", 14 "12:57*" 15 ], 16 [ 17 "3", 18 "ccc", 19 "13:00*", 20 "3", 21 "13:00*" 22 ], 23 [ 24 "4", 25 "ddd", 26 "13:00*", 27 "4", 28 "13:00*" 29 ], 30 [ 31 "", 32 "vvv", 33 "14:12*", 34 "", 35 "14:12*" 36 ], 37 [ 38 "", 39 "xxx", 40 "15:36*", 41 "", 42 "15:36*" 43 ], 44 [ 45 "", 46 "yyy", 47 "18:05*", 48 "", 49 "18:05*" 50 ], 51 [ 52 "", 53 "zzz", 54 "", 55 "", 56 "" 57 ] 58]

困っていること

通過順位順では並びますし、通過順位が空文字の時は下にまとめて表示することもできますが、
通過順位が空文字のグループを、さらに通過タイム順で絞り込むロジックが思い浮かびません。
頭がフットーしそうです。誰か助けて :-(

環境情報

Amazon Linux2 Apache 2.4 PHP 7.4

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

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

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

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

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

m.ts10806

2022/10/05 10:44

>MySQLで言うところの GROUP BY rank ORDER BY rank ASC, time ASC みたいなことがしたい CSVの記録をDBに登録すれば良いのでは。
qwe001

2022/10/06 01:10

コメントありがとうございます。他社レンタルサーバを使用しますので、予算の関係でDBは使えないです。PHP側での並び替えが難しくても、最終的にフロントで見た目上、並び変われば良いのでlodash.jsなどで並び替えても良いかな、ってみてて思いました
guest

回答1

0

自己解決

自己解決しました。typoが原因でした。

/** * 値の大小比較を行う * 空文字は一番下にする */ function compare($row1, $row2) { $row1Rank = $row1[0]; $row2Rank = $row2[0]; $row1Time = $row1[2]; $row2Time = $row2[2]; if($row1Rank === $row2Rank) { // 空白や同一文字が連続した時 //return 0; if($row1Time === $row2Time){ return 0; } else if($row1Time == ""){ return 1; } else if($row2Time == ""){ // <- ここを$row2Rank にしてた return -1; } return $row1Time <=> $row2Time; } else if($row1Rank === "") { return 1; } else if($row2Rank === "") { return -1; } return $row1Rank <=> $row2Rank; }

投稿2022/10/06 01:50

qwe001

総合スコア133

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問