LoginSignup
0
0

【PHP】開発現場で必ず使う配列関数のすべて

Last updated at Posted at 2024-02-17

はじめに

webサービスを構築していく中で必要な知識を備忘録として残しております。

今回は 配列関数 について深堀りしていきたいと思います。
※随時writeしていきます。

現場でよく使う配列関数

配列関数 説明 使用頻度
in_array 配列の要素に特定の値を含むものがあるか ★★★★★
count 配列の要素の数を返す ★★★★★
array_merge 配列同士を結合(マージ)する ★★★★
array_push 配列の末尾に要素を追加する ★★★
array_chunk 配列を指定した要素を持つ配列に分解する ★★★
array_column 配列から特定単一カラムの配列を取得する ★★★

in_array

概要

配列の要素に特定の値を含むものがあるかをチェックする関数

第一引数:配列内で検索される値
第二引数:検索対象の配列
第三引数:型チェックまで実施するかどうか(比較を厳密に行うかどうか)
戻り値:bool (true・false)

in_array(mixed $needle, array $haystack, bool $strict = false): bool

使用例

<?php
$colors = ['red', 'blue', 'orange'];

// -- 1
if(in_array('blue', $colors, true)) {
    echo 'blueは配列内に存在します';
} else {
    echo 'blueは配列内に存在しません';
}

// -- 2
if(in_array('black', $colors, true)) {
    echo 'blackは配列内に存在します';
} else {
    echo 'blackは配列内に存在しません';
}
?>
1 : blueは配列内に存在します
2 : blackは配列内に存在しません

多次元配列の場合

後に説明する array_column を使用し判定処理を実施

<?php
$colors = [
    ['color' => 'red', 'number' => '1'],
    ['color' => 'blue', 'number' => '2'],
    ['color' => 'orange', 'number' => '3']
];

// -- 1
if(in_array('blue', array_column($colors, 'color'), true)) {
    echo 'blueは配列内に存在します';
} else {
    echo 'blueは配列内に存在しません';
}

// -- 2
if(in_array('black', array_column($colors, 'color'), true)) {
    echo 'blackは配列内に存在します';
} else {
    echo 'blackは配列内に存在しません';
}
?>
1 : blueは配列内に存在します
2 : blackは配列内に存在しません

代替ロジックとのパフォーマンス比較

in_array VS array_search VS isset

  • in_array
<?php
// 検証用10万テストデータ生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = 'test' . '_'.  $i;
}

$start = microtime(true);

if(in_array('test_99999', $tests, true)) {
    $finished = true;
};

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.000694秒
  • array_search
<?php
// 検証用10万テストデータ生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = 'test' . '_'.  $i;
}

$start = microtime(true);

$key = array_search('test_99999', $tests);

if ($key !== false) {
    $finished = true;
} 

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.000582秒
  • isset
<?php
// 検証用10万テストデータ生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = 'test' . '_'.  $i;
}

$start = microtime(true);

// issetを使用するにはキーと値を反転させる必要がある
$tests = array_flip($tests);

if(isset($tests['test_99999'])) {
    $finished = true;
};

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.004728秒
  • 結果
    in_arrayarray_search は同等のパフォーマンス結果となった。
    なので、パフォーマンス的にはどちらでも良いと思いますが、戻り値がそれぞれ違うため、状況に応じて使い分けが必要だと思います。
    in_array : bool、array_search : key値 or false)
    issetで判定する場合 array_flipをする必要があるため、その分遅くなっていた。

count

概要

配列やオブジェクトの要素数を数えるために使用する関数

第一引数:要素数を数える対象の配列やカウンタブルなオブジェクト
第二引数:デフォルトは COUNT_NORMAL です。COUNT_RECURSIVE を指定すると、多次元配列の場合に再帰的に要素を数えます
戻り値:int

count(mixed $array_or_countable, int $mode = COUNT_NORMAL): int

使用例

$colors = ['red', 'blue', 'orange'];
$count = count($colors);
echo "要素数: $count";
要素数: 3

多次元配列の場合

<?php
$colors = [
    ['color' => 'red', 'number' => '1'],
    ['color' => 'blue', 'number' => '2'],
    ['color' => 'orange', 'number' => '3'],
    ['color' => 'black', 'number' => '4']
];
$count = count($colors);
echo "要素数: $count";
?>
要素数: 4
  • mode = COUNT_RECURSIVE
<?php
$colors = [
    ['color' => 'red', 'number' => '1'],
    ['color' => 'blue', 'number' => '2'],
    ['color' => 'orange', 'number' => '3'],
    ['color' => 'black', 'number' => '4']
];
$count = count($colors, COUNT_RECURSIVE);
echo "要素数: $count";
?>
要素数: 12

要素数8 + 配列数4 で12とカウントされます。使い道はあまりなさそう。

代替ロジックとのパフォーマンス比較

count VS sizeof

  • count
<?php
// 検証用10万テストデータ生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = 'test' . '_'.  $i;
}

$start = microtime(true);

$count = count($tests);

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.000001秒
  • sizeof
<?php
// 検証用10万テストデータ生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = 'test' . '_'.  $i;
}

$start = microtime(true);

$count = sizeof($tests);

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.000006秒

単純に配列の要素数を取得するのは count がパフォーマンスが良い結果がでました。

array_merge

概要

複数の配列を結合するための関数

第一引数:結合する最初の配列
第二引数:結合する他の配列(複数指定可能)
戻り値:配列

array_merge(array $array1, array ...$arrays): array

使用例

<?php
$array1 = ["red", "blue"];
$array2 = ["orange"];

$mergedArray = array_merge($array1, $array2);

print_r($mergedArray);
?>
Array
(
    [0] => red
    [1] => blue
    [2] => orange
)

連想配列の場合

<?php
$array1 = ["r" => "red", "b" => "blue"];
$array2 = ["o" => "orange"];
$array3 = ["w" => "white"];

$mergedArray = array_merge($array1, $array2, $array3);

print_r($mergedArray);
?>
Array
(
    [r] => red
    [b] => blue
    [o] => orange
    [w] => white
)
  • 重複キーがある場合
<?php
$array1 = ["r" => "red", "b" => "blue"];
$array2 = ["o" => "orange"];
$array3 = ["b" => "black"];

$mergedArray = array_merge($array1, $array2, $array3);

print_r($mergedArray);
?>
Array
(
    [r] => red
    [b] => black
    [o] => orange
)

キー:b は二つ存在するが、blackで上書きされてしまう。

多次元配列の場合

<?php
$colors = [
    ['color' => 'red', 'number' => '1'],
    ['color' => 'blue', 'number' => '2'],
    ['color' => 'orange', 'number' => '3'],
    ['color' => 'black', 'number' => '4']
];

$colors2 = [
    ['color' => 'white', 'number' => '5'],
    ['color' => 'pink', 'number' => '6'],
];

$mergedArray = array_merge($colors, $colors2);

print_r($mergedArray);
?>
Array
(
    [0] => Array
        (
            [color] => red
            [number] => 1
        )

    [1] => Array
        (
            [color] => blue
            [number] => 2
        )

    [2] => Array
        (
            [color] => orange
            [number] => 3
        )

    [3] => Array
        (
            [color] => black
            [number] => 4
        )

    [4] => Array
        (
            [color] => white
            [number] => 5
        )

    [5] => Array
        (
            [color] => pink
            [number] => 6
        )
)

代替ロジックとのパフォーマンス比較

array_merge VS + 演算子 VS array_merge_recursive

  • array_merge
<?php
// 検証用10万テストデータ1生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = ['test' => $i];
}

// 検証用10万テストデータ2生成
$tests2 = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests2[] = ['test2' => $i];
}

$start = microtime(true);

$mergedArray = array_merge($tests,$tests2);

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.004547秒
  • + 演算子
<?php
// 検証用10万テストデータ1生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = ['test' => $i];
}

// 検証用10万テストデータ2生成
$tests2 = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests2[] = ['test2' => $i];
}

$start = microtime(true);

$mergedArray = $tests + $tests2;

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.003017秒
  • array_merge_recursive
<?php
// 検証用10万テストデータ1生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = ['test' => $i];
}

// 検証用10万テストデータ2生成
$tests2 = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests2[] = ['test2' => $i];
}

$start = microtime(true);

$mergedArray = array_merge_recursive($tests,$tests2);

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.004963秒

すべて同等のパフォーマンスが出る結果となった。
ただし、今回はキー指定なしの多次元配列で検証したが、重複ありだと array_merge_recursiveのパフォーマンスが著しく落ちる結果も見られた。
また、キー重複ありの場合、array_mergeは上書きするに対して、+ 演算子は最初の配列の値が優先されます。(先勝ち)
その特性も踏まえての使い分けが必要です。

array_push

概要

配列の末尾に一つ以上の要素を追加するための関数

第一引数:要素を追加する対象の配列(参照渡し)
第二引数:追加する要素。複数の要素を一度に追加することができます
戻り値:int (配列要素数)

array_push(array &$array, mixed $value1, mixed $value2, ...): int

使用例

<?php
$colors = ["red", "blue"];

array_push($colors, "orange", "black");

print_r($colors);
?>
Array
(
    [0] => red
    [1] => blue
    [2] => orange
    [3] => black
)

代替ロジックとのパフォーマンス比較

array_push VS [] 演算子

  • array_push
<?php
// 検証用10万テストデータ1生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests["test_1_$i"] = 'test' . '_'.  $i;
}


$start = microtime(true);

$results = [];
foreach ($tests as $test) {
    array_push($results, $test);
}

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.006505秒
  • [] 演算子
<?php
// 検証用10万テストデータ1生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests["test_1_$i"] = 'test' . '_'.  $i;
}


$start = microtime(true);

$results = [];
foreach ($tests as $test) {
    $results[] = $test;
}

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.005865秒

array_push[] 演算子 が同等のパフォーマンスだが、[] 演算子 のほうが速い結果となった。
検証件数より多いデータ量だと差は開いていくので、パフォーマンス的には[] 演算子を使用するほうが良いと言える。

array_chunk

概要

配列を指定されたサイズで分割するための関数

第一引数:分割する対象の配列
第二引数:各チャンクのサイズを指定します
第三引数:キーを保持するかどうかを指定するフラグ。デフォルトは false で、キーが再インデックス化されます
戻り値:配列

array_chunk(array $input, int $size, bool $preserve_keys = false): array

使用例

<?php
$colors = ['red','blue','orange','black','white','pink','yellow','green','brown'];

$chunks = array_chunk($colors, 3);

print_r($chunks);
?>
Array
(
    [0] => Array
        (
            [0] => red
            [1] => blue
            [2] => orange
        )

    [1] => Array
        (
            [0] => black
            [1] => white
            [2] => pink
        )

    [2] => Array
        (
            [0] => yellow
            [1] => green
            [2] => brown
        )

)
  • 多次元配列の場合
$colors = [
    ['color' => 'red', 'number' => '1'],
    ['color' => 'blue', 'number' => '2'],
    ['color' => 'orange', 'number' => '3'],
    ['color' => 'black', 'number' => '4'],
    ['color' => 'white', 'number' => '5'],
    ['color' => 'pink', 'number' => '6'],
    ['color' => 'yellow', 'number' => '7'],
    ['color' => 'green', 'number' => '8'],
    ['color' => 'brown', 'number' => '9'],
];

$chunks = array_chunk($colors, 3);

print_r($chunks);
Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [color] => red
                    [number] => 1
                )

            [1] => Array
                (
                    [color] => blue
                    [number] => 2
                )

            [2] => Array
                (
                    [color] => orange
                    [number] => 3
                )

        )

    [1] => Array
        (
            [0] => Array
                (
                    [color] => black
                    [number] => 4
                )

            [1] => Array
                (
                    [color] => white
                    [number] => 5
                )

            [2] => Array
                (
                    [color] => pink
                    [number] => 6
                )

        )

    [2] => Array
        (
            [0] => Array
                (
                    [color] => yellow
                    [number] => 7
                )

            [1] => Array
                (
                    [color] => green
                    [number] => 8
                )

            [2] => Array
                (
                    [color] => brown
                    [number] => 9
                )

        )

)

array_column

概要

多次元配列から指定した列(キー)の値だけを抽出して新しい配列を生成するための関数

第一引数:対象の多次元配列
第二引数:抽出したい列のキー。これは、連想配列の場合はキー、数値添字の場合はインデックスとなります
第三引数:新しい配列のインデックスとして使用する列のキー。省略すると数値添字が使用されます
戻り値:配列

aarray_column(array $input, mixed $column_key, mixed $index_key = null): array

使用例

<?php
$colors = [
    ['color' => 'red', 'number' => '1'],
    ['color' => 'blue', 'number' => '2'],
    ['color' => 'orange', 'number' => '3'],
    ['color' => 'black', 'number' => '4']
];

$color = array_column($colors, 'color');

print_r($color);
?>
Array
(
    [0] => red
    [1] => blue
    [2] => orange
    [3] => black
)

代替ロジックとのパフォーマンス比較

array_column VS array_map VS foreach

  • array_column
<?php
// 検証用10万テストデータ生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = ['number' => $i , 'key' => 'test'. '_' .$i];
}


$start = microtime(true);

$color = array_column($tests, 'number');

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.004329秒
  • foreach
<?php
// 検証用10万テストデータ生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = ['number' => $i , 'key' => 'test'. '_' .$i];
}


$start = microtime(true);

$numbers = [];

foreach ($tests as $test) {
    $numbers[] = $test['number'];
}

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.014227秒
  • array_map
<?php
// 検証用10万テストデータ生成
$tests = [];
for( $i = 0; $i < 100000; ++$i ){
  $tests[] = ['number' => $i , 'key' => 'test'. '_' .$i];
}


$start = microtime(true);

$color = array_map(function($test) {
    return $test["number"];
}, $tests);

$end = microtime(true);

echo sprintf("%.6f",($end - $start)) . '秒';
?>
0.013517秒

array_column がパフォーマンスが良い結果となった。
特定の要件を満たす場合は、シンプルで効果的といえます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0