kakakakakku blog

Weekly Tech Blog: Keep on Learning!

PHP で array_flatten を実現する

Ruby だと Array で .flatten が使えるけど,PHP の Array には無くて自分で実装する必要があるということで!

PHP で flatten

SPL (Standard PHP Library) にある再帰関数を使って実装できた.簡単にイメージを書いておくと,RecursiveArrayIterator で Array からイテレータオブジェクトを生成して RecursiveIteratorIterator で葉を刈り取って,最後に iterator_to_array で配列に戻すって感じ.

ちなみに RecursiveIteratorIterator の第二引数に「刈り取りモード」を指定できて,デフォルトだと RecursiveIteratorIterator::LEAVES_ONLY で葉を対象にしている.RecursiveIteratorIterator::SELF_FIRSTRecursiveIteratorIterator::CHILD_FIRST だと親と葉が対象になる.

最初 RecursiveIteratorIterator ってクラス名を見たときに「イテレーターイテレーター」の冗長さに笑ってしまったwww

<?php

  $nested_array = array(
    1,
    2,
    3,
    array(
      'A',
      'B',
      'C',
      array(
       'D1',
       'D2',
       'D3'
      )
    ),
    4,
    5,
    6
  );

  // Array
  // (
  //     [0] => 1
  //     [1] => 2
  //     [2] => 3
  //     [3] => Array
  //         (
  //             [0] => A
  //             [1] => B
  //             [2] => C
  //             [3] => Array
  //                 (
  //                     [0] => D1
  //                     [1] => D2
  //                     [2] => D3
  //                 )
  // 
  //         )
  // 
  //     [4] => 4
  //     [5] => 5
  //     [6] => 6
  // )
  echo print_r($nested_array, true);

  // Array
  // (
  //     [0] => 1
  //     [1] => 2
  //     [2] => 3
  //     [3] => A
  //     [4] => B
  //     [5] => C
  //     [6] => D1
  //     [7] => D2
  //     [8] => D3
  //     [9] => 4
  //     [10] => 5
  //     [11] => 6
  // )
  echo print_r(array_flatten($nested_array), true);

  function array_flatten($nested_array) {
    return iterator_to_array(new RecursiveIteratorIterator(new RecursiveArrayIterator($nested_array)), false);
  }

同じコードを playground に push しておいた.

(参考)Ruby だと

[1] pry(main)> [1, 2, 3, ['A', 'B', 'C', ['D1', 'D2', 'D3']], 4, 5, 6].flatten
[
  [ 0] 1,
  [ 1] 2,
  [ 2] 3,
  [ 3] "A",
  [ 4] "B",
  [ 5] "C",
  [ 6] "D1",
  [ 7] "D2",
  [ 8] "D3",
  [ 9] 4,
  [10] 5,
  [11] 6
]