Метод reduce
Метод reduce класса Crawler применяет пользовательскую callback-функцию последовательно к каждому элементу узла и накапливает единый результат. Первым параметром передаётся callback-функция, которая принимает аккумулятор и текущий узел DOMElement. Вторым параметром можно передать начальное значение аккумулятора. Метод возвращает итоговое накопленное значение.
Синтаксис
$crawler->reduce(callable $callback, mixed $initial = null)
Пример
Давайте создадим Crawler с несколькими элементами и объединим их текстовое содержимое в одну строку через запятую:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DomCrawler\Crawler;
class ArticleController extends AbstractController
{
public function index(): Response
{
$html = '<ul><li>abcde</li><li>article</li><li>hello</li></ul>';
$crawler = new Crawler($html);
$res = $crawler->filter('li')->reduce(function ($carry, $node) {
return $carry === '' ? $node->textContent : $carry . ', ' . $node->textContent;
}, '');
return new Response($res);
}
}
?>
Результат выполнения кода:
"abcde, article, hello"
Пример
Давайте посчитаем суммарную длину текста всех элементов списка:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DomCrawler\Crawler;
class ArticleController extends AbstractController
{
public function index(): Response
{
$html = '<ul><li>abcde</li><li>article</li><li>hello</li></ul>';
$crawler = new Crawler($html);
$res = $crawler->filter('li')->reduce(function ($carry, $node) {
return $carry + strlen($node->textContent);
}, 0);
return new Response((string) $res);
}
}
?>
Результат выполнения кода:
"17"
Пример
Давайте соберём массив значений атрибутов data-id из всех элементов:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DomCrawler\Crawler;
class ArticleController extends AbstractController
{
public function index(): Response
{
$html = '<div><span data-id="1">abcde</span><span data-id="2">article</span><span data-id="3">hello</span></div>';
$crawler = new Crawler($html);
$res = $crawler->filter('span')->reduce(function ($carry, $node) {
$carry[] = $node->getAttribute('data-id');
return $carry;
}, []);
return new Response(implode(', ', $res));
}
}
?>
Результат выполнения кода:
"1, 2, 3"