1

私は途方に暮れています。私はグーグルで検索し、ここで検索し、PHPマニュアルを何時間も読みましたが、解決策が思いつきません.

次の配列構造を取得しました。

[x] => Array
    (
        ...
                  [object_name_1] => Array
                      (
                          [db] => x
                          [form] => y
                          [value] => z
                      )

                  ...

                  [object_name_4] => Array
                      (
                          [db] => x
                          [form] => y
                          [value] => z
                      )
                  ...

                  [object_name_n] => Array
                      (
                          [db] => x
                          [form] => y
                          [value] => z
                      )
...
[y] => Array
    (
        ...
        [object_group_xyz] => Array
           (
                  [object_name_a] => Array
                      (
                          [db] => x
                          [form] => y
                          [value] => z
                      )

                  ...
           )
                  ...

                  [object_name_e] => Array
                      (
                          [db] => x
                          [form] => y
                          [value] => z
                      )
                  ...

                  [object_name_z] => Array
                      (
                          [db] => x
                          [form] => y
                          [value] => z
                      )

今、私の問題は次のとおりです。すべての object_name_x 配列を保存したいです。配列の深さは不明です。実際には、さまざまな object_name_n オブジェクトの深さが同じ配列に依存している可能性があります。しかし、それらは常に最後の葉です。

どうすればこの問題を解決できますか。私が知る限り、RecursiveIteratorIterator が最後から 2 番目のオブジェクトのみを考慮する方法はありません。

私の出力は次のようになります。

Array
(
    [object_name_1] => Array
        (
            [db] => x
            [form] => y
            [value] => z
        )
        ...
    [object_name_4] => Array
        (
            [db] => x
            [form] => y
            [value] => z
        )
        ...
    [object_name_n] => Array
        (
            [db] => x
            [form] => y
            [value] => z
        )
        ...
    [object_name_a] => Array
        (
            [db] => x
            [form] => y
            [value] => z
        )
        ...
    [object_name_e] => Array
        (
            [db] => x
            [form] => y
            [value] => z
        )
        ...
    [object_name_z] => Array
        (
            [db] => x
            [form] => y
            [value] => z
        )
        ...
)

お時間をいただきありがとうございます。

4

2 に答える 2

2

これはイテレータ クラスの組み込み機能ではありませんが、 を使用しRecursiveIteratorIteratorてスタックを構築し、リーフに到達するとすぐに 1 ステップ戻ることができます。

以下は PoC に近いものです。これは非常にクリーンなソリューションではありませんが、動作し、原則を実証する必要があります。

class MyIterator extends RecursiveIteratorIterator {
  protected $stack = array();
  protected $result = array();

  public function __construct($data)
  {
    parent::__construct(new RecursiveArrayIterator($data), RecursiveIteratorIterator::SELF_FIRST);
  }
  public function getObjects()
  {
    foreach($this as $dummy);
    return $this->result;
  }

  public function rewind()
  {
    parent::rewind();
    $this->stack = array();
    $this->result = array();
    $this->pushIfNoLeaf();
  }
  public function next()
  {
    parent::next();
    $this->pushIfNoLeaf();
  }
  public function beginIteration()
  {
    parent::beginIteration();
    $this->popIfLeaf();
  }
  public function beginChildren()
  {
    parent::beginChildren();
    $this->popIfLeaf();
  }
  protected function pushIfNoLeaf()
  {
    if ($this->getSubIterator()->hasChildren()) {
      $this->stack[] = array('key' => $this->key(), 'value' => $this->current());
    }
  }
  protected function popIfLeaf()
  {
    if (!$this->getSubIterator()->hasChildren()) {
      $item = array_pop($this->stack);
      $this->result[$item['key']] = $item['value'];
    }
  }
}
$data = array(
'obj1' => array(1,2,3),
'arr1' => array(
  'obj2' => array(4,5,6),
  'obj3' => array(7,8,9)
)
);

$iterator = new MyIterator($data);
var_dump($iterator->getObjects());

出力例

array(3) {
  ["obj1"]=>
  array(3) {
    [0]=>
    int(1)
    [1]=>
    int(2)
    [2]=>
    int(3)
  }
  ["obj2"]=>
  array(3) {
    [0]=>
    int(4)
    [1]=>
    int(5)
    [2]=>
    int(6)
  }
  ["obj3"]=>
  array(3) {
    [0]=>
    int(7)
    [1]=>
    int(8)
    [2]=>
    int(9)
  }
}

デモ

于 2013-03-31T18:35:50.177 に答える