Iterables (قابل پیمایش)

نوع iterable در PHP — آرایه‌ها، Iterator، Generator و پیمایش داده‌ها با yield

Iterable چیست؟

Iterable هر چیزی است که می‌توان آن را با foreach پیمایش کرد. در PHP دو نوع iterable اصلی داریم:

استفاده از iterable به‌عنوان نوع

<?php
function processItems(iterable $items) {
    foreach ($items as $item) {
        echo $item . "<br>";
    }
}

// آرایه کار می‌کند
processItems([1, 2, 3]);

// Iterator هم کار می‌کند
processItems(new ArrayIterator([1, 2, 3]));
?>

is_iterable — بررسی iterable

<?php
var_dump(is_iterable([1, 2, 3]));           // true
var_dump(is_iterable(new ArrayIterator()));  // true
var_dump(is_iterable("hello"));              // false
var_dump(is_iterable(123));                  // false
?>

رابط Iterator

کلاسی که Iterator را پیاده‌سازی می‌کند، قابل پیمایش است:

<?php
class NumberRange implements Iterator {
    private $start;
    private $end;
    private $current;

    public function __construct($start, $end) {
        $this->start = $start;
        $this->end = $end;
        $this->current = $start;
    }

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

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

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

    public function rewind() {
        $this->current = $this->start;
    }

    public function valid() {
        return $this->current <= $this->end;
    }
}

foreach (new NumberRange(1, 5) as $key => $value) {
    echo "$key => $value<br>";
}
// 0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5
?>

Generator — yield

Generator روشی ساده برای ساخت iterable بدون نیاز به پیاده‌سازی Iterator:

<?php
function numberRange($start, $end) {
    for ($i = $start; $i <= $end; $i++) {
        yield $i;
    }
}

foreach (numberRange(1, 5) as $number) {
    echo $number . "<br>";
}
// 1, 2, 3, 4, 5
?>
Generator حافظه کمتری مصرف می‌کند چون مقادیر را یکی‌یکی تولید می‌کند، نه همه را همزمان.

Generator با کلید و مقدار

<?php
function keyValueGenerator() {
    yield "name" => "علی";
    yield "age" => 25;
    yield "city" => "تهران";
}

foreach (keyValueGenerator() as $key => $value) {
    echo "$key: $value<br>";
}
?>

Generator برای داده‌های بزرگ

<?php
// خواندن فایل خط به خط بدون بارگذاری کل فایل
function readLines($filename) {
    $file = fopen($filename, "r");
    while (!feof($file)) {
        yield trim(fgets($file));
    }
    fclose($file);
}

foreach (readLines("large_file.txt") as $lineNumber => $line) {
    echo "خط $lineNumber: $line<br>";
}
?>

yield from — ترکیب Generatorها

<?php
function inner() {
    yield 1;
    yield 2;
    yield 3;
}

function outer() {
    yield 0;
    yield from inner();
    yield 4;
}

foreach (outer() as $n) {
    echo $n;  // 0, 1, 2, 3, 4
}
?>

IteratorAggregate — ساده‌تر از Iterator

<?php
class Collection implements IteratorAggregate {
    private $items = [];

    public function add($item) {
        $this->items[] = $item;
    }

    public function getIterator() {
        return new ArrayIterator($this->items);
    }
}

$col = new Collection();
$col->add("سیب");
$col->add("موز");

foreach ($col as $item) {
    echo $item . "<br>";
}
?>

توابع مفید iterable

تابعتوضیح
iterator_to_array()تبدیل iterator به آرایه
iterator_count()تعداد عناصر
iterator_apply()اعمال تابع روی هر عنصر

این مبحث بخشی از دوره آموزش کامل PHP است.

ابزارهای مرتبط