🌚

PHP 配列の基礎

2022/04/18に公開

社内向けの資料としてこちらを用意しました。配列処理について知っておいてほしい基礎知識をまとめたので順番に見ていきましょう。

基本の形

まずは基本の配列の形を見て行きましょう。

1次元配列

まずは、単純な一列の配列から始めましょう。

/** 定義 **/
$array = ['ペン', 'ノート', 'ケース', '付箋', '消しゴム'];

/** CRUD **/
// Create
$array[] = 'マグネット';
array_push($array, 'ボトルケース');
// Read
echo $array[0] # ペンが出力
// Update
echo $array[1]; # ノートが出力
$array[1] = 'ルーズリーフ';
echo $array[1]; # ルーズリーフが出力
// Delete
unset($array[1]);
array_values($array); # 削除後はインデックスごと抜け落ちてしまうので必須
// 初期化(リセット)
unset($array);
$array = [];

/** ループ処理 **/
// for
for($i = 0; $i < count($array); $i++{
    echo $array[$i];
}
// foreach
foreach($array as $value){
    echo $value;
}

/** デバッグ **/
// 配列の形式に問わず同じのため次回以降は省略します
print_r($array); # 比較的配列の形が見やすい
var_dump($array); # データの型まで見ることができる

問題

では、上記を踏まえて問題に取り組んでみましょう!
練習用配列

$array = ['Mark', 'Github', 'Star', 'Merge', 'Request'];

練習環境(好きな方を選択)
https://paiza.io/ja/projects/new
https://3v4l.org/

問題1
上記配列$arrayのデータを出力例に従い全件表示してください。(デバッグではないです)
出力例 1: Mark, 2: Github ...(1スタートです)

回答(サンプル)
$array = ['Mark', 'Github', 'Star', 'Merge', 'Request'];
for($i = 0; $i < count($array); $i++){
    $key = $i + 1;
    echo $key . ' : ' . $array[$i] . "\n";
}

問題2
ループ処理で配列を出力させる中で、インデックスが偶数の場合値を全て'PHP'に変更してください。
最後に、デバッグで出力してください

回答(サンプル)
$array = ['Mark', 'Github', 'Star', 'Merge', 'Request'];
foreach($array as $key => $value){
    if($key % 2 === 0){
        $array[$key] = 'PHP';
    }
}
var_dump($array);

多次元配列

では次に、階層が深い配列処理をしてみましょう。際限が無いので、今回は2次元配列を扱います。

/** 定義 **/
$array = [
    ['ペン'], ['ノート', 'ケース'], ['付箋', '消しゴム']
];

/** CRUD **/
// Create
# 'ペン'がある配列に追加したい場合
$array[0][] = 'マグネット';
array_push($array[0], 'クリップ');
# 新規配列データを追加したい場合
$array[] = ['風船', 'カード', 'シート'];
array_push($array, ['ボトルケース']);
// Read
echo $array[1][1] # ノートが出力
// Update
print_r($array[1][1]); # ケースが出力
$array[1] = ['ルーズリーフ'];
print_r($array[1][1]);  # ルーズリーフが出力
// Delete
unset($array[1]); # ['ノート', 'ケース']が削除される
array_values($array); # 削除後はインデックスごと抜け落ちてしまうので必須

/** ループ処理 **/
// for
for($i = 0; $i < count($array); $i++){
    $innerArray = $array[$i];
    // ループをネスト(入れ子)する
    for($j = 0; $j < count($innerArray); $j ++){
	    echo $innerArray[$j];
    }
}
// foreach
foreach($array as $data){
    foreach($data as $value){
        echo $value;
    }
}

問題

練習用配列

$array = [
    ['ペン'], ['ノート', 'ケース'], ['付箋', '消しゴム']
];

問題1
上記配列$arrayのデータを出力例に従い全件表示してください。(デバッグではないです)
出力例 1: ペン、2: ノート、3: ケース、4: 付箋、5: 消しゴム

回答(サンプル)
$array = [
    ['ペン'], ['ノート', 'ケース'], ['付箋', '消しゴム']
];

$num = 1; # 番号管理用
foreach($array as $data){
    foreach($data as $value){
        echo $num . ' : ' . $value . "\n";
        $num ++;
    }
}

連想配列

最後に、キーと値がセットになった連想配列です。

/** 定義 **/
$array = [
    'name' => 'John',
    'age' => 28,
    'hobby' => 'Baseball'
];

/** CRUD **/
// Create
# 新しいキーを作る
$array['pref'] = '千葉県';
// array_push()は使えないのでarray_merge() + 再代入
$array = array_merge($array, ['pref' => '千葉県']);
// Read
echo $array['name'] # Johnが出力
// Update
$array['name'] = 'Mike';
print_r($array['name']);  # Mikeが出力
// Delete
unset($array['hobby']); # 'hobby' => 'Baseball'が削除される
array_values($array); # 削除後はインデックスごと抜け落ちてしまうので必須

/** ループ処理 **/
// for
# 連想配列のキーを取得
$keys = array_keys($array);
for($i = 0; $i < count($array); $i++){
    echo $keys[$i] . ' : ' . $array[$keys[$i]] . "\n";
}
// foreach
foreach($array as $key => $value){
    echo $key . ' : ' . $value . "\n";
}

問題

練習用配列

$nameList = ['Kenta', 'Mike', 'Paker', 'Joseph', 'Taiki'];
$ageList = [20, 42, 35, 26, 30];
$hobbyList = ['baseball', 'game', 'sing', 'reading', 'programming'];

$array = [
    'name' => 'John',
    'age' => 28,
    'hobby' => 'Baseball'
];

問題1
上記配列$arrayのデータを出力例に従い全件表示してください。(デバッグではないです)
出力例 name: John、age: 28 ...

回答(サンプル)
$array = [
    'name' => 'John',
    'age' => 28,
    'hobby' => 'Baseball'
];

foreach($array as $key => $value){
    echo $key . ' : ' . $value . "\n";
}

問題2
$nameList, $ageList, $hobbyListからそれぞれランダムにデータを抽出し、
$arrayのような連想配列のデータを5件作成してください。(※データの重複はあっても良い)
最後にprint_r()で出力しましょう。

回答(サンプル)
$nameList = ['Kenta', 'Mike', 'Paker', 'Joseph', 'Taiki'];
$ageList = [20, 42, 35, 26, 30];
$hobbyList = ['baseball', 'game', 'sing', 'reading', 'programming'];
// 格納先
$userList = [];
for($i = 0; $i < 5; $i ++){
    // 定義 + 初期化
    $personalData = []; 
    // ランダム生成したインデックスで検索
    $personalData['name'] = $nameList[rand(0,4)];
    $personalData['age'] = $ageList[rand(0,4)];
    $personalData['hobby'] = $hobbyList[rand(0,4)];
    // 配列を丸ごと投入して良いのでarray_push()
    array_push($userList, $personalData);
}

print_r($userList);

特殊な配列処理

Json型のデータの扱い

異なる言語間の処理や、APIとデータの連携を行う際にPHPの配列で送ってしまうと相手側で受け取って処理をすることができません。そこで、配列をjsonにすることでデータ連携がしやすくなります。逆に、jsonで受け取ったデータはPHPの配列に変換してあげることで扱いやすいデータとなるでしょう。

PHP配列 => jsonの変換

$array = [
    'name' => 'John',
    'age' => 28,
    'hobby' => 'Baseball'
];

$array = json_encode($array);
// jsonは配列では無いのでechoで出力する
echo $array;

json => PHP配列の変換

$array = [
    'name' => 'John',
    'age' => 28,
    'hobby' => 'Baseball'
];

$array = json_encode($array);
/** 先程の続きから **/
$array = json_decode($array);
// 配列になっているのでvar_dumpで出力
var_dump($array);

配列の検索

一次元配列から検索

array_search()関数は、キーワードに一致した値が配列にあればインデックスを返し、値が無ければfalseを返します。また、似た関数でin_array()関数がありますが、こちらは値がある場合インデックスは返さずtrueとだけ返します。

saple.php
$result = array_search('キーワード', $array);
if($result){
  // 検索結果があった場合の処理
}else{
  // 検索結果がなかった場合の処理
}

多次元配列から検索

多次元配列は、やはり階層が深いので一回で検索は難しいです。
そのため、array_column()関数で対象要素を切り抜いて一次元配列とし、array_search()関数で検索をします。ただし、array_search()の特性として、複数検索結果があったとしても一番最初のインデックスしか返さないので複数結果がある場合は別の処理が必要です。

sample.php
$array = [
    ['John', 28, 'Baseball'],
    ['Ryota', 20, 'sing'],
    ['Kenta', 32, 'running'],
    ['Mike', 33, 'game'],
];
// name一覧を取得
$nameList = array_column($array, 0); //インデックスで検索
// 抽出
$result = array_search('John', $nameList);
var_dump($result);

連想配列から検索

連想配列は、多次元配列とかなり似ています。
やはり階層が深くなってしまうため、一度array_column()で抽出してからarray_search()で検索をします。

sample.php
$array = [
    [
        'name' => 'John',
        'age' => 28,
        'hobby' => 'Baseball'
    ],
    [
        'name' => 'Ryota',
        'age' => 20,
        'hobby' => 'sing'
    ],
    [
        'name' => 'Kenta',
        'age' => 32,
        'hobby' => 'running'
    ],
    [
        'name' => 'Mike',
        'age' => 33,
        'hobby' => 'game'
    ],
];
// name一覧を取得
$nameList = array_column($array, 'name');
// 抽出
$result = array_search('John', $nameList);
var_dump($result);

// 以下のやり方でもOKです
$result = array_filte($array, function ($row){
    return $row['name'] === 'John';
});

配列の結合

一次元配列

配列の結合は、array_merge()関数を用いることで結合ができます。array_push()では結合はできず、配列が1つの要素として追加されてしまいます。(特に記載しませんが個人的に試してみてください)

さらに、連想配列の場合はarray_merge()関数を用いると結合ではなく要素の上書きになってしまうので注意が必要です。(上書きされる特性も上手く活かせそうですが)

$array_1 = ['A', 'B', 'C', 'D', 'E'];
$array_2 = ['F', 'G', 'H', 'I'];
array_merge($array_1, $array_2);

多次元配列

多次元配列に、配列を丸ごと追加したい場合はarray_push()を用いることで追加できます。

$array = [
    ['A', 'B', 'C'],
    ['D', 'E', 'F'],
    ['G', 'H', 'I'],
];
$addItem = ['X', 'Y', 'Z'];
array_push($array, $addItem);

連想配列

連想配列の結合は、array_merge()などでは上書きされてしまいます。
データの扱い方にもよりますが、array_merge_recursive()関数を用いれば以下のように
データを結合することができます。

$data_1 = [
    'id' => 1,
    'name' => 'Taro',
    'pref' => 'Tokyo',
];
$data_2 = [
    'id' => 2,
    'name' => 'Jiro',
    'pref' => 'Chiba',
];

array_merge_recursive($data_1, $data_2);

2つの配列から連想配列を作成する

array_combine()関数を用いることで、2つの配列を連想配列とすることができます。

$array_1 = ['UID1947', 'UID7602', 'UID0185'];
$array_2 = ['Keen', 'Been', 'Leen'];
$result = array_combine($array_1, $array2);

/*
'UID1947' => 'Keen',
'UID7602' => 'Been', ...
*/

配列からnullを排除する

array_filter()で配列からnullや空白を解除できますが、indexごと抜けてしまいます。
そのため、array_values()で採番し直すことで綺麗なnullの排除が可能です。

$array = [null, 1, 2, 3, null, 4, 5, null, 7];
$result = array_values(array_filter($array));

配列データに対して一括で処理をする

配列のデータに対して、同一の処理をしたいとなった場合、ループをせずarray_map()関数を用いることで一気に処理をすることが可能です。
使い方は、array_map('関数名', $対象配列);となっており、関数は自作でも構いません。

$array = ['1', '2', '3', '4', '5'];
$result = array_map('intval', $array);

以上です!何かあればまた小ネタを追加していきます!

Discussion