日々、徒然プログラミング。

都内のIT系専門学校に通う、一人暮らし女子学生chocoffeeの、 日々の気づきと学び、たまにほっこりを綴るブログ。

エンジニアのみなさま、エンジニアの卵のみなさま、IT業界のみなさまが
わたしの「チームってなんだ?」というぼやきに反応してくださることを祈って。

PHP

こんにちは!
近所のいつものカフェでご満悦してるちょこひです。

今日突然暑くなった!
朝からルンルンで洗濯回せるのはいいけども
暑いのだいっきらいなんでやめてほしい!


アカン

今日はPHPのsort関数について書きます。
夏休み明けたらすぐ定期テストがあるため最近重い腰を上げて
ようやっと勉強し始めたんですが

昨日見事にソート関連でハマりました。

ググりにググりまくり
友達に確認してなんとかなったので
書き留めておきます。


今日使うもの


さて、sort関数の話をする前にソートされるものを用意しましょう。
今回は2つ用意します。
 
$array = array('かきくけこ', 'さしすせそ', 'あいうえお');
$dict = array('chocolate' => 'チョコレート', 'apple' => 'リンゴ', 'banana' => 'バナナ');

$arrayはよくみる配列です。
Javaと同じように、0から順にインデックスが振られます。
要素数3つの配列です。

$dictは「連想配列」です。要素とキーがセットになったもの。
Swiftでは辞書って呼ばれるものです。 


では、ソート関数のお話。
PHPには、いろんなソート関数が用意されています。

・sort
・rsort
・ksort
・krsort
・asort
・arsort

今回はこれらの整理です。 


普通の配列の場合

 まずは普通の配列をソートする場合についてまとめます。

 
$array = array('かきくけこ', 'さしすせそ', 'あいうえお');
$result = sort($array);
print_r($array);


実行結果が以下です。

Array
(
    [0] => あいうえお
    [1] => かきくけこ
    [2] => さしすせそ
)

sort関数は、要素を昇順でソートし、インデックスを振りなおします
戻り値はboolean。成功時にtrue、失敗時にfalseが入ります。
ここでは$resultにはtrueが入っています。


では、rsort関数は
$array = array('かきくけこ', 'さしすせそ', 'あいうえお');
$result = rsort($array);
print_r($array);
 
実行結果が以下です。

Array
(
    [0] => さしすせそ
    [1] => かきくけこ
    [2] => あいうえお
)

rsort関数は、要素を降順でソートし、インデックスを振り直します
sort関数同様、戻り値はbooleanです。


続いてksort関数。
$array = array('かきくけこ', 'さしすせそ', 'あいうえお');
$result = ksort($array);
print_r($array);
 
 
実行結果が以下です。

Array
(
    [0] => かきくけこ
    [1] => さしすせそ
    [2] => あいうえお
)

ksortのkは、「key」の略です。キーを昇順に並べ替えて配列を作成します
ここではkeyは自動で振られたインデックス順なので、実行前と結果が変わりません。

ここまでくればわかるかと思いますが、
krsortは
$array = array('かきくけこ', 'さしすせそ', 'あいうえお');
$result = krsort($array);
print_r($array);

実行結果は

Array
(
    [2] => あいうえお
    [1] => さしすせそ
    [0] => かきくけこ
)
こうなります。

では、asort。

$array = array('かきくけこ', 'さしすせそ', 'あいうえお');
$result = asort($array);
print_r($array);
 

実行結果は

Array
(
    [2] => あいうえお
    [0] => かきくけこ
    [1] => さしすせそ
)

asortはsortと違い、
キーと値のセットを維持したまま要素の昇順で並べ替えます
asortは連想配列でやると違いがよくわかるので、連想配列で同じことをしてみます。


連想配列の場合

では、連想配列で同じことをしてみます。
まずはsortから。
$dict = array('chocolate' => 'チョコレート', 'apple' => 'リンゴ', 'banana' => 'バナナ');
$result = sort($dict);
print_r($dict);

実行結果
Array
(
    [0] => チョコレート
    [1] => バナナ
    [2] => リンゴ
)

キーがどっかいきました。

同じように、ksortでも試してみましょう。

$dict = array('chocolate' => 'チョコレート', 'apple' => 'リンゴ', 'banana' => 'バナナ');
$result = ksort($dict);
print_r($dict);

実行結果は

Array
(
    [apple] => リンゴ
    [banana] => バナナ
    [chocolate] => チョコレート
)
キーと値の関係を維持しながらキーの昇順に並べ替えられ、再度インデックスが追加されています。

では、asortは
 
$dict = array('chocolate' => 'チョコレート', 'apple' => 'リンゴ', 'banana' => 'バナナ');
$result = asort($dict);
print_r($dict);

実行結果は

Array
(
    [chocolate] => チョコレート
    [banana] => バナナ
    [apple] => リンゴ
)

キーと値を維持したまま、要素の昇順で再度インデックスが振られています。

連想配列を要素の昇順/降順でソートしたい時、
sort / rsort関数を使ってしまうとキーが失われてしまいます。

困っちゃう。

そんな時に一役買うのがasort / arsort関数ってな感じです。
 
まとめ


エラい硬くなりましたが、こんな感じ。
最初普通にsort関数を使ってキーがどっかいっちゃって、
Σ(゚д゚;) こうなってました。

にしてもややこしいなあ!
PHPはややこしいです。

Javaのありがたみをかみしめながら引き続き勉強します!



ちょこひ 

こんにちは!
西新宿から大久保までノンストップウォーキングしてお眠なちょこひです。

例えるなら、小学生の頃の2コマ続きの水泳授業の後のような、心地よい眠気。
現実は豪雨と強風の中ビッチョビチョになりながら歩いただけです。
今日も(いつも通り)たくさん眠れそう。


三項演算子って?

今日は春から学び始めたPHPの三項演算子の話をするためだけに
眠い目をこすりながら執筆しています。

三項演算子は、プログラミングの世界では有名ですよね。
条件分岐の手法でよく用いられています。

知らない方のためにちょこっと説明してみます。

「Aさんの名前が太郎くんならTaro、次郎くんならJiro、それ以外ならSaburoと出力する」
というプログラミングを組むとしましょう。

Javaで考えてみると、以下のようになります。

16/06/14追記
Javaで文字列の==はよくないんでした・・・epuals()ですね。
一応動くは動くのですが、あとから修正するかもしれません。



if(aName == "太郎") {			//もし太郎だったら
	System.out.print("Taro");	//Taroと出力
} else if(aName == "次郎") {		//もし次郎だったら
	System.out.print("Jiro");	//Jiroと出力
} else {				//それ以外は
	System.out.print("Saburo");	//Saburoと出力
} 



プログラミングを全く知らない方でも、
なんとなく仕組みがわかるのではないでしょうか。


イコールが2つ続いていますが、これは情報の世界では等号として扱われています


(`・д・´) 「じゃあイコール1つはなんなんだよ!」

イコール一つの場合は、
右辺のものを左辺のものに代入」という意味になります。
等しくありません。代入です。


以下をご覧ください。 
number = number + 1;	


数学者「等しくねえよなーに言ってんだこいつ」
プログラマ「numberは1増えるのか〜 numberが1なら2になるな


こんな感じ。


プログラマ「number って2回書くのだるい…」
で、生まれたのが以下の書き方。


number += 1;	


どんどん短くなってますね。
これも、numberに1を足したものをnumberに代入する、という意味です。


話が逸れましたが、つまり何が言いたいのかっていうと
プログラマはとおおおおおおおおってもめんどくさがりなので
何でもかんでも短く書きたがるんです。


最初の太郎さんたちのコードを見てみましょう。

if(aName == "太郎") {			//もし太郎だったら
	System.out.print("Taro");	//Taroと出力
} else if(aName == "次郎") {		//もし次郎だったら
	System.out.print("Jiro");	//Jiroと出力
} else {				//それ以外は
	System.out.print("Saburo");	//Saburoと出力
} 

プログラマ「なげーよ!!!(゚Д゚)ゴルァ!!」


もちろん、もっと短く書く方法が存在します。 
その一つが三項演算子です。


ふー!導入ながかったあ!!!

 
三項演算子はすごい


ひっぱりましたが、実際に三項演算子を使ってみましょう。

if(aName == "太郎") {			//もし太郎だったら
	System.out.print("Taro");	//Taroと出力
} else if(aName == "次郎") {		//もし次郎だったら
	System.out.print("Jiro");	//Jiroと出力
} else {				//それ以外は
	System.out.print("Saburo");	//Saburoと出力
} 

これが、 
String name = aName == "太郎" ? "Taro" : aName == "次郎" ? "Jiro" : "Saburo";	//条件分岐
System.out.print(name);								//出力命令

こうなる。

('A`) 「わかんねえ」

こちらも解説してみます。 

Stringは、nameには文字列が入るよ!と指定しています。あんま気にしなくていいです。

aName == "太郎" の部分は、イコール2つなので「Aさんの名前は太郎だ!」と言ってます。
これは正しいor誤り の2パターンになりますね。
正しい場合は、?のすぐ後の"Taro"がnameに代入されます。
誤りの場合は、:の後に進みます

すると、「Aさんの名前は次郎だ!」と言ってます。これも2パターンになりますね。
正しい場合は、?のすぐ後の"Jiro"がnameに代入され、
誤りの場合は"Saburo"が代入されます。

やってることは同じなのに、書く量が全然違いますね。
三項演算子はプログラマにモッテモテ。
これが、三項演算子はすごい理由です。

まとめると、

example = a == b ? a : b;

aとbが等しいならexampleにはaが、
等しくないならexampleにはbが代入される、
これが三項演算子です。

 
PHPの三項演算子

では、PHPでも同じ三項演算子を書いてみましょう。
ちょっとだけ書式が違うのですが、書いてあることは一緒です。

$name = $aName == "太郎" ? "Taro" : $aName == "次郎" ? "Jiro" : "Saburo";
echo $name;

書けた。
echoは出力命令です。

さて、aNameを太郎にして動かしてみると・・・


(`・д・´) 「Jiroになった」


・・・次郎だと?


 (`・д・´) 「Jiroになった」


・・・花子なら?


  (`・д・´) 「Saburoになった」



花子がSaburoになったことは放っておいて、 
太郎くん消失事件が発生しました。

太郎くんはどこに行ったのか?
もしかしてPHPは太郎くんに親を殺された恨みがあるのか?
もしかしてPHPは太郎の文字列に反応して正常に動かなくなるバグがあるのか?
もしかしてPHPは問答無用で私のコードを受け付けないのか?
もしかしてPHPは三項演算子使えない?


(・∀・)「仕様がちがうだけやで」 


Javaを始めとする他の言語の大多数は、
三項演算子の動きは同じです。
太郎くんたちの例で言うなら、nameはTaro、Jiro、Saburoの3通りになります。

PHPは、それがちょっと違って、
nameはJiroとSaburoの2通りになってしまうようで。 

具体的にいうと、
$aName == "太郎" 〜 == "次郎"
の部分が正しい場合は"Jiro"に、誤りの場合は"Saburo"になる、らしい。

$name = ($aName == "太郎" ? "Taro" : ($aName == "次郎" ? "Jiro" : "Saburo"));
echo $name;

かっこによって優先順位を変えてあげると、
ちゃんと太郎くんは戻ってきてくれました。
よかったね、太郎くん。


・・・花子ちゃんがSaburoになってる問題は知りません。
わたしわるくない。


まとめ


さて、いつになく真面目な文になりました。
眠い時の方が真面目にかける仕様なわたし。意味がわかりません。

一応PHPの仕様を読んでみたのですが、
そもそもPHPでは三項演算子の入れ子(太郎くんたちのまさにあれ)は
推奨されていないようです。

確かに条件分岐が多いなら他の書き方を使ったほうが
可読性はあるかもしれませんね。

この問題に直面した時はPHPだけ仕様が違うことに
全く解せていませんでした。
激おこぷんぷんまるでした(古い)

いっこいっこ確認しながら勉強を進めていこうと思います。


とりあえず今日は眠い!お家帰って寝るんだー!!!



ちょこひ 

↑このページのトップヘ