<commit_before><?php
namespace ManaPHP\Dom;

class SelectorList implements \Iterator
{
    /**
     * @var array
     */
    protected $_full_xpath = [];

    /**
     * @var \ManaPHP\Dom\Selector[]
     */
    protected $_selectors;

    /**
     * @var int
     */
    protected $_position = 0;

    /**
     * SelectorList constructor.
     *
     * @param \ManaPHP\Dom\Selector[] $selectors
     * @param array                   $xpaths
     */
    public function __construct($selectors, $xpaths)
    {
        $this->_selectors = $selectors;
        $this->_full_xpath = $xpaths;
    }

    /**
     * @return string[]
     */
    public function extract()
    {
        $data = [];
        foreach ($this->_selectors as $node) {
            $data[] = $node->extract();
        }

        return $data;
    }

    /**
     * @param string $default
     *
     * @return string
     */
    public function extract_first($default = null)
    {
        return $this->_selectors ? $this->_selectors[0]->extract() : $default;
    }

    /**
     * @param string $path
     *
     * @return static
     */
    public function xpath($path)
    {
        if ($path === '') {
            return clone $this;
        }

        $new_selectors = [];
        foreach ($this->_selectors as $selector) {
            $r = $selector->xpath($path);
            if ($r) {
                /** @noinspection SlowArrayOperationsInLoopInspection */
                $new_selectors = array_merge($new_selectors, $r->_selectors);
            }
        }

        return new SelectorList($new_selectors, array_merge($this->_full_xpath, [$path]));
    }

    /**
     * @param string $css
     *
     * @return static
     */
    public function css($css)
    {
        if ($css === '') {
            return clone $this;
        }

        return $this->xpath((new CssToXPath())->transform($css));
    }

    /**
     * @param string          $field
     * @param callable|string $func
     *
     * @return static
     */
    public function filter($field = null, $func = null)
    {
        if ($field === '') {
            return clone $this;
        }

        if ($field !== null && $field[0] === '!') {
            $field = substr($field, 1);
            $not = true;
        } else {
            $not = false;
        }

        if (is_string($func)) {
            $is_preg = in_array($func[0], ['@', '#'], true) && substr_count($func, $func[0]) >= 2;
        }

        $new_selectors = [];
        foreach ($this->_selectors as $selector) {
            if ($field === null) {
                $value = $selector;
            } elseif (strpos($field, '()') !== false) {
                if ($field === 'text()') {
                    $value = $selector->text();
                } elseif
                ($field === 'html()') {
                    $value = $selector->html();
                } elseif
                ($field === 'node()') {
                    $value = $selector->node();
                } else {
                    throw new Exception('invalid field');
                }
            } else {
                $value = $selector->attr($field);
            }

            if ($func === null) {
                $r = $value !== null;
            } elseif (is_string($func)) {
                $r = $is_preg ? preg_match($func, $value) : strpos($value, $func) !== false;
            } else {
                $r = $func($value);
            }

            if (($not && !$r) || (!$not && $r)) {
                $new_selectors[] = $selector;
            }
        }

        return new SelectorList($new_selectors, $this->_full_xpath);
    }

    /**
     * @param string $regex<commit_msg>Modified   ManaPHP/Dom/SelectorList.php<commit_after><?php
namespace ManaPHP\Dom;

class SelectorList implements \Iterator
{
    /**
     * @var array
     */
    protected $_full_xpath = [];

    /**
     * @var \ManaPHP\Dom\Selector[]
     */
    protected $_selectors;

    /**
     * @var int
     */
    protected $_position = 0;

    /**
     * SelectorList constructor.
     *
     * @param \ManaPHP\Dom\Selector[] $selectors
     * @param array                   $xpaths
     */
    public function __construct($selectors, $xpaths)
    {
        $this->_selectors = $selectors;
        $this->_full_xpath = $xpaths;
    }

    /**
     * @return string[]
     */
    public function extract()
    {
        $data = [];
        foreach ($this->_selectors as $node) {
            $data[] = $node->extract();
        }

        return $data;
    }

    /**
     * @param string $default
     *
     * @return string
     */
    public function extract_first($default = null)
    {
        return $this->_selectors ? $this->_selectors[0]->extract() : $default;
    }

    /**
     * @param string $path
     *
     * @return static
     */
    public function xpath($path)
    {
        if ($path === '') {
            return clone $this;
        }

        $new_selectors = [];
        foreach ($this->_selectors as $selector) {
            $r = $selector->xpath($path);
            if ($r) {
                /** @noinspection SlowArrayOperationsInLoopInspection */
                $new_selectors = array_merge($new_selectors, $r->_selectors);
            }
        }

        return new SelectorList($new_selectors, array_merge($this->_full_xpath, [$path]));
    }

    /**
     * @param string $css
     *
     * @return static
     */
    public function css($css)
    {
        if ($css === '') {
            return clone $this;
        }

        return $this->xpath((new CssToXPath())->transform($css));
    }

    /**
     * @param string          $field
     * @param callable|string $func
     *
     * @return static
     */
    public function filter($field = null, $func = null)
    {
        if ($field === '') {
            return clone $this;
        }

        if ($field !== null && $field[0] === '!') {
            $field = substr($field, 1);
            $not = true;
        } else {
            $not = false;
        }

        if (is_string($func)) {
            $is_preg = in_array($func[0], ['@', '#'], true) && substr_count($func, $func[0]) >= 2;
        }

        $new_selectors = [];
        foreach ($this->_selectors as $selector) {
            if ($field === null) {
                $value = $selector;
            } elseif (strpos($field, '()') !== false) {
                if ($field === 'text()') {
                    $value = $selector->text();
                } elseif
                ($field === 'html()') {
                    $value = $selector->html();
                } elseif
                ($field === 'node()') {
                    $value = $selector->node();
                } else {
                    throw new Exception('invalid field');
                }
            } else {
                $value = $selector->attr($field);
            }

            if ($func === null) {
                $r = $value !== '';
            } elseif (is_string($func)) {
                $r = $is_preg ? preg_match($func, $value) : strpos($value, $func) !== false;
            } else {
                $r = $func($value);
            }

            if (($not && !$r) || (!$not && $r)) {
                $new_selectors[] = $selector;
            }
        }

        return new SelectorList($new_selectors, $this->_full_xpath);
    }

    /**
     * @param string $regex
{'fraction_non_alphanumeric': 0.1622462787550744, 'fraction_numerical': 0.0018944519621109607, 'mean_word_length': 1.3973402530003243, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2333188', 'n_tokens_mistral': 2197, 'n_tokens_neox': 2124, 'n_words': 435}