ボム君.com

Masa's blog

今まで学んできたITスキルを主に。

PHPで、配列の中身の一部分だけを削除したい場合

PHPでの配列に対する関数っていうものはたくさんあって、


PHPのドキュメンテーションにも色々記述されているようですが、



ここではよく使う関数を元に、解決策を見つけていこいうと思います。


配列の中身をまずはどうなっているか、確認します。


配列の中身全てを出力させるには、PHPのプリント関数である、「print_r 」を使います。

<?php
$arr = array(1,2,3,4,5,6,7,8,9);
print_r($arr);
?>

上記のように、「print_r」を使えば、下記にように配列が出力します。

Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 )

配列には、インデックスがあり、一つ一つの値が「=>」の後に出力しています。



では内容の確認が取れましたので、ここから本題です。

中身を削除する

プログラムを書いてるうちに、配列の中身を削除したい、消したい、取り出しでまた新しい配列を作りたい、などの問題に直面すると思います。

そんな時のために、PHPでは配列に対する関数がいくつか用意されています。

array_diff_key()

どの位置(インデックス、またはキー)を削除したいか、わかっている場合はこの関数がオススメです。


例えば下記のように、一番左と左から三番目の値を削除したかったら、このように書きます。

<?php
$array = array(1,2,3,4,5,6,7,8,9);
$array = array_diff_key($array, [0 => "なんでもいい", "2" => "なんでもいい"]);
print_r($array);
?>


上の出力はこのようになります。

Array ( [1] => 2 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 )

1と3がちゃんと消されてますね。


array_dif()

どの位置(インデックス、またはキー)を削除したいか、わからなかった場合は、

array_dif()関数を使います。

<?php
$array = array(1,2,3,4,5,6,7,8,9);
$array = array_diff($array, [1, 2]);
print_r($array);
?>

これもとても簡単で、関数内に、配列と、削除したい値をあげれるだけです。

上のコードの出力はこのようになります。

Array ( [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 )

見ての通り、1と2が消されてますね。


array_values()

ここで注意です。


上の二つの方法さえ理解し、覚えていれば、配列上の削除は問題なく、かけるようになると思いますが、


やはり、ここで、気づく人もいるかもしれません。


削除された後の配列をようく見てみてください。


インデックスの数が変わっていないことにお気づきでしょうか。


例えば、

配列A   :$array = array(1,2,3,4,5,6,7,8,9);
後の配列A :Array ( [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 ) 

値が3のインデックスは「0」ではなく、元の位置である「2」が置かれています。


本来ならば、この場合、ループで、新しい配列に移動し、インデックスを作り直すといった感じの方法をやると思いますが、


PHPではこういった問題に直面した場合の解決策がすでに作られています。



その関数がarray_values()です。

<?php
$array = array(1,2,3,4,5,6,7,8,9);
$array = array_values(array_diff($array, [1, 2]));
print_r($array);
?>

出力

Array ( [0] => 3 [1] => 4 [2] => 5 [3] => 6 [4] => 7 [5] => 8 [6] => 9 )

このように配列を出力させる前に、その配列をarray_valuesにぶち込めておけば、このPHP配列関数が

勝手に整理してくれるっていうことになります。

とても便利で、よく使う関数の一つですので、ぜひ覚えて活用してください。


では。

PHP: 配列を一列ずつ出力させる方法

配列は一般的に一行ずつ出力しますが、

時には一列ずつ出力することだってあります。

方法は二つあります。

PHP関数:array_column

プログラム

<?php
$a = array(
  array(
    'id' => 5698,
    'first_name' => 'Bill',
    'last_name' => 'Gates',
  ),
  array(
    'id' => 4767,
    'first_name' => 'Steve',
    'last_name' => 'Jobs',
  )
  array(
    'id' => 3809,
    'first_name' => 'Mark',
    'last_name' => 'Zuckerberg',
  )
);

$last_names = array_column($a, 'last_name');
print_r($last_names);
?>

出力

Array
(
  [0] => Gates
  [1] => Jobs
  [2] => Zuckerberg
)

このように配列が 「キー => 値」 という形のフォーマットであれば、array_column使って、簡単に出力させることができます。

簡単なアルゴリズムで出力

キーがなく、ただインデックスで割り当てられている配列の場合は上記の方法は使えません。

<?php
$a = array(array(1,2,3),array(4,5,6)); //最初の配列
$new_a = array(); //出力用の配列
$column = count($a[0]); //列の数

//まず最初の配列全てを一行の配列にする
foreach($a as $a_items){
	foreach($a_items as $a_items_item){
		array_push($new_a, $a_items_item);
	}
}
//一行だけの配列に、「%」演算子で列ごとに分ける。
for($i=0;$i<count($new_a);$i++){
	$temp[$i%$column] .= $new_a[$i];
}
print_r($temp);
?>

出力

Array ( [0] => 14 [1] => 25 [2] => 36 )

プログラミングチャレンジ:学生スコア計算式

問題:

  1. 学生の最終成績を次の5の倍数にする。
  2. 最終成績が40以下の場合は不合格。
  3. 満点は100点。
  4. 最終成績と元の成績の差が3以下の場合は元の成績を最終成績にする。


Sample Input

4
73
67
38
33

Sample Output

75
67
40
33
<?php

$handle = fopen ("php://stdin", "r");
function roundUpToAny($n,$x=5) {
    return round(($n+$x/2)/$x)*$x;
}

function solve($grades){
    // Complete this function
    for($i = 0; $i<count($grades);$i++){
        $score = $grades[$i];
        if($score >= 38){
            $roundscore = roundUpToAny($score);
            $grades[$i] = (abs($score - $roundscore)<3)?$roundscore:$score;
        }
    }
    
    return $grades;
}

fscanf($handle, "%d",$n);
$grades = array();
for($grades_i = 0; $grades_i < $n; $grades_i++){
   fscanf($handle,"%d",$grades[]);
}
$result = solve($grades);
echo implode("\n", $result)."\n";





?>

Vimの基礎3

まずここまで見て来たVimの基礎のまとめをここで。

今までのVim基礎ブログはこちら:
masa25michi.hatenablog.com

masa25michi.hatenablog.com

これまでのまとめ

h, I  文字
j, k  行
w, b, e  単語
^, $  最初/最後の行
(, )  文
{, }  段落

Vimの基礎2

コマンドモード上でカーソルを移動する方法は前にも述べたが、ここでも詳しく。

単語移動

w  次の単語に移動

b  後ろの単語に移動

e  次の単語、または行の最後の単語に移動

行移動

)  次の行に移動

(  後ろの行に移動

段落移動

}  次の段落に移動

{  後ろの段落に移動

行の最初と最後の文字に移動

^  行の最初に移動

$  行の最後に移動

ファイルの最初と最後の行に移動

1G  ファイルの最初の行に移動

G  ファイルの最後の行に移動

ファイルの任意の行に移動

nG  ファイルのn行目に移動

ファイル内での位置とファイルの状態 ,行数を表示

Ctrl + g  ファイルの行数を表示

Vimの基礎1

Vimとは

ターミナル上でのエディターのこと。

なぜ必要かというと、サーバー内のファイルを直接ターミナル上で編集できるから。


IDEEclipseNetbeansSublime)などを使う方が多いかもしれないが、いちいちファイルのパス(位置)を把握しなければいけないのがめんどい。

マニュラルでIDEを開いて操作するより、ターミナルでcdやたlsやらlnなどを使ってファイルを確認しviコマンドで開いたほうが効率が良い場合が多い。

特に、エミュレータの環境下では非常に活躍する。



あとは、Vimを使っているプログラマーはモテるという。

MacUnixLinuxのターミナルを開く

vim はターミナル上で使うソフトウェア。
なのでターミナルは必要不可欠。

コマンドモード と インサートモード

Vimには二種類のモードがある。
コマンドモード と インサートモード。

コマンドモードは今開いてるファイルに対しての命令文を書き込むみ用。
インサートモードは普通に今開いているファイルを編集する用。

この二つの切り替えは、
キーボードの「i」でインサートモードに。
キーボードの「esc」でコマンドモードに。

コマンドモードでよく使うコマンド 一覧

「カーソル移動」

  • h  1文字左に移動
  • j  1行したに移動
  • k 1行上に移動
  • l 1文字右に移動
  • H 画面の一番上の行
  • L 画面の一番下の行

「削除」

  • x カーソル上の1文字を削除
  • X  カーソル上の左の文字を削除
  • xx  カーソル上の行を削除

「検索」

  • / 順方向に文字列を検索
  • ? 逆方向に文字列を検索


「アンドゥ & リドゥ」

  • u 直前の操作をやめる
  • U 行ごとやめる

「ファイル操作」

  • :w  ファイルを保存
  • :r  次の行に他のファイルの内容を入れる
  • Ctrl + g ファイルの状態、名前などを表示する

「終了」

  • :wq ファイルに保存して終了
  • :q 終了(ファイルを保存してない場合はエラーが発生する)
  • :q! 強制終了

viでファイルを読み込む。ファイルがディレクトリに存在しない場合は、勝手に作られる。

vi text.txt

キーボードの「i」でインサートモードにする

適当に文字列を入れたら、「esc」でインサートモードをやめ、「:w」でファイルを保存

Viを終了したい時は、コマンドモード上で「:wq」

コマンドモードのコマンド

上記によく使うコマンド一覧をのせたが、他にも

右方向キー 左方向キー 上方向キー 下方向キー

でカーソルの位置を変える。

スペースキー もしくは Shift+スペースキー

で次の文字に移動。

バックスペースキー

で前の文字に移動

ターミナルコマンド ファイル/ディレクトリの作成、削除、移動などの、よく使うコマンド5つ

ファイルのないフォルダーを削除する場合

rmdir ディレクトリ名

もしファイルやフォルダーがそのディレクトリにあった場合はエラーが出力される

$ rmdir sample
rmdir: failed to remove `sample': Directory not empty

ファイルのないディレクトリ内に別の空のディレクトリを削除したい場合

rmdir -p olddir1/olddir2/olddir3

注意点として、指定したディレクトリすべてが空である必要がある。
でなければエラーが出力される。

ちなみに上記のコマンドは下記と一緒。

rmdir olddir1/olddir2/olddir3 olddir1/olddir2 olddir1

中身のある(ファイルなどがある)ディレクトリ(フォルダー)を削除したい場合はrmdirは使えないため、下記のようにコマンド入力する。

rm -rf ディレクトリ名

すべてのサブディレクトリも削除される。
これは非常に危険なコマンドかもしれない。
入力するときは気をつけたほうがいい。

中身のある(ファイルなどがある)ディレクトリ(フォルダー)を削除するときに確認を出力させる場合、

rm -ir ディレクトリ
rm -i ファイル名

Linuxユーザー、もしくはMacユーザーの方はこちらをオススメする。

コマンドに別名をつける

「alias」 コマンドでコマンドに名前をつけることができる。

alias rm="rm -i"

上のようにかくと、次からrmを入力すると、必ず確認も付いてくる。

alias rm="rm -v"

たくさんの使い方があり、プログラマーによってはaliasでのネーミーングにも違いがでてくる。