15

array_map をイテレータとして行う方法はありますか?

例えば:

foreach (new MapIterator($array, $function) as $value)
{
   if ($value == $required)
      break;
}

これを行う理由は、$function の計算が難しく、$array の要素が多すぎるため、特定の値が見つかるまでマッピングする必要があるためです。array_map は、必要な値を検索する前にすべての値を計算します。

イテレータを自分で実装することもできますが、これを行うネイティブな方法があるかどうかを知りたいです。PHPドキュメントを検索しても何も見つかりませんでした。

4

8 に答える 8

6

要するに:いいえ。

PHP に組み込まれている遅延反復子マッピングはありません。非遅延関数iterator_apply()がありますが、あなたが求めているようなものはありません。

あなたが言ったように、あなたは自分で書くことができます。IteratorIteratorを拡張し、単純にcurrent()メソッドをオーバーライドすることをお勧めします。

そのようなものがあれば、ここまたはここに文書化されます。

于 2011-07-04T08:38:40.427 に答える
1

キーの配列と値の配列を使用する単純な Map クラスの実装を考えています。全体的な実装は、Java の Iterator クラスのように使用できますが、次のように繰り返します。

while ($map->hasNext()) {
  $value = $map->next();
  ...
}
于 2011-07-03T23:15:48.317 に答える
0

その目的でコールバックを使用するために、このクラスを作成しました。使用法:

$array = new ArrayIterator(array(1,2,3,4,5));
$doubles = new ModifyIterator($array, function($x) { return $x * 2; });

定義 (必要に応じて自由に変更してください):

class ModifyIterator implements Iterator {
    /**
     * @var Iterator
     */
    protected $iterator;

    /**
     * @var callable Modifies the current item in iterator
     */
    protected $callable;

    /**
     * @param $iterator Iterator|array
     * @param $callable callable This can have two parameters
     * @throws Exception
     */
    public function __construct($iterator, $callable) {
        if (is_array($iterator)) {
            $this->iterator = new ArrayIterator($iterator);
        }
        elseif (!($iterator instanceof Iterator))
        {
            throw new Exception("iterator must be instance of Iterator");
        }
        else
        {
            $this->iterator = $iterator;
        }

        if (!is_callable($callable)) {
            throw new Exception("callable must be a closure");
        }

        if ($callable instanceof Closure) {
            // make sure there's one argument
            $reflection = new ReflectionObject($callable);
            if ($reflection->hasMethod('__invoke')) {
                $method = $reflection->getMethod('__invoke');
                if ($method->getNumberOfParameters() !== 1) {
                    throw new Exception("callable must have only one parameter");
                }
            }
        }

        $this->callable = $callable;
    }

    /**
     * Alters the current item with $this->callable and returns a new item.
     * Be careful with your types as we can't do static type checking here!
     * @return mixed
     */
    public function current()
    {
        $callable = $this->callable;
        return $callable($this->iterator->current());
    }

    public function next()
    {
        $this->iterator->next();
    }

    public function key()
    {
        return $this->iterator->key();
    }

    public function valid()
    {
        return $this->iterator->valid();
    }

    public function rewind()
    {
        $this->iterator->rewind();
    }
}
于 2014-07-09T21:12:04.900 に答える
0
foreach ($array as $key => $value) {
   if ($value === $required) {
      break;
   } else {
      $array[$key] = call_back_function($value);
   }
}

必要な値が見つかるまで処理を繰り返します。

于 2011-07-04T03:23:43.173 に答える
0

イテレータを気にしないでください。答えは次のとおりです。

foreach ($array as $origValue)
{
   $value = $function($origValue);
   if ($value == $required)
      break;
}
于 2012-04-17T18:37:45.680 に答える