nkopylov/php-typed-collections

为PHP实体生成静态类型集合

v0.0.1 2022-10-04 07:36 UTC

This package is auto-updated.

Last update: 2024-09-04 11:39:46 UTC


README

Source Code Latest Version Software License PHP Version Build Status Coverage Status Total Downloads

为PHP实体生成静态类型集合。

集合示例

<?php
/**
* Autogenerated.
* Time: 2022-10-04 06:17:44
*/

declare(strict_types=1);

namespace Nkopylov\Test\PhpCollections;

use JetBrains\PhpStorm\Pure;
use Nkopylov\Test\PhpCollections\TestClass as CollectionEntity;

/**
 * Autogenerated typed collection for Nkopylov\Test\PhpCollections\TestClass objects.
 * Check nkopylov/php-typed-collections for more information
 *
 * @implements \Iterator<mixed, CollectionEntity>
 * @implements \ArrayAccess<mixed, CollectionEntity>
 * @codeCoverageIgnore
 */
class TestCollection_testCollection implements \Iterator, \ArrayAccess {

    /**
     * @var CollectionEntity[]
     */
    private array $elements = [];

    /**
     * @var callable
     */
    private $idMapper;

    /**
     * @phpstan-pure
     * Creates new collection
     * @return static
     */
    public static function create(): self
    {
        return new static(function() {static $counter = 0; return $counter++;});
    }

    final public function __construct(callable $idMapper)
    {
        $this->idMapper = $idMapper;
    }

    /**
     * @phpstan-pure
     * Returns the first entity from the collection.
     * @return CollectionEntity|null
     */
    public function first(): ?CollectionEntity
    {
        if ($this->count() === 0) {
            return null;
        }

        $this->rewind();

        return $this->current();
    }

    /**
     * {@inheritdoc}
     * @return CollectionEntity
     */
    public function current(): CollectionEntity
    {
        $entity = current($this->elements);

        if ($entity === false) {
            throw new \LogicException('Collection is empty');
        }

        return $entity;
    }

    /**
     * {@inheritdoc}
     */
    public function next(): void
    {
        next($this->elements);
    }

    /**
     * {@inheritdoc}
     */
    public function key(): mixed
    {
        return key($this->elements);
    }

    /**
     * {@inheritdoc}
     */
    public function valid(): bool
    {
        return $this->key() !== null;
    }

    /**
     * {@inheritdoc}
     */
    public function rewind(): void
    {
        reset($this->elements);
    }

    /**
     * {@inheritdoc}
     */
    public function offsetExists($offset): bool
    {
        return isset($this->elements[$offset]);
    }

    /**
    * {@inheritdoc}
    */
    public function offsetSet($offset, $value): void
    {
        if (!($value instanceof CollectionEntity)) {
            throw new \InvalidArgumentException(sprintf("Can't insert object of class %s to %s", get_class($value), self::class));
        }

        $this->elements[$offset] = $value;
    }

    /**
    * {@inheritdoc}
    */
    public function offsetUnset($offset): void
    {
        unset($this->elements[$offset]);
    }

    /**
     * {@inheritdoc}
     */
    public function offsetGet($offset): CollectionEntity
    {
        return $this->elements[$offset];
    }

    /**
     * Add entity to the collection
     * @param CollectionEntity $item
     * @return $this
     */
    public function add(CollectionEntity $item): self
    {
        $this->elements[($this->idMapper)($item)] = $item;
        return $this;
    }

    /**
     * Add entities from array to the collection
     * @param iterable<CollectionEntity> $items
     * @return $this
     */
    public function addArray(iterable $items): self
    {
        foreach ($items as $item) {
            $this->add($item);
        }

        return $this;
    }

    /**
     * Remove entity from collection by id
     * @param mixed $id
     * @return $this
     */
    public function remove($id): self
    {
        unset($this->elements[$id]);
        return $this;
    }

    /**
     * Check if entity exists by id
     * @param mixed $id
     * @return bool
     */
    public function has($id): bool
    {
        return isset($this->elements[$id]);
    }

    /**
     * Get entity by id.
     * @param mixed $id
     * @return CollectionEntity|null
     */
    public function get($id): ?CollectionEntity
    {
        return $this->elements[$id] ?? null;
    }

    /**
     * @phpstan-pure
     * Map collection by given callable. Creates new collection
     * @param callable $mapper
     * @return static
     */
    public function map(callable $mapper): self
    {
        return (new static($this->idMapper))
               ->addArray(array_map($mapper, $this->elements));
    }

    /**
     * @phpstan-pure
     * Creates a new collection mapped by key defined by given callable
     * @param callable $idMapper
     * @return static
     */
    public function mapKeys(callable $idMapper): self
    {
        return (new static($idMapper))->addArray($this->elements);
    }

    /**
     * Map collection to array by given callable.
     * @param callable $mapper
     * @return array<mixed, CollectionEntity>
     */
    public function mapToArray(callable $mapper): array
    {
        return array_map($mapper, $this->elements);
    }

    /**
     * Transform current collection with given function
     * @param callable $mapper
     * @return $this
     */
    public function transform(callable $mapper): self
    {
        $this->elements = array_map($mapper, $this->elements);
        return $this;
    }

    /**
     * @phpstan-pure
     * Filter collection by given callback. Returns new collection
     * @param callable $mapper
     * @return static
     */
    public function filter(callable $mapper): self
    {
        return (new static($this->idMapper))->addArray(array_filter($this->elements, $mapper) ?? []);
    }

    /**
     * Sort collection by given callback
     * @param callable $sorter
     * @return $this
     */
    public function sort(callable $sorter): self
    {
        uasort($this->elements, $sorter);
        return $this;
    }

    /**
     * @phpstan-pure
     * Split collection on the given number of chunks. Returns array of new collections
     * @param int $size
     * @return array<int, self>
     */
    public function chunk(int $size): array
    {
        return array_map(
            fn(array $chunk) => (new static($this->idMapper))->addArray($chunk),
            array_chunk($this->elements, $size)
        );
    }

    /**
     * @phpstan-pure
     * Groups collection by some value returned by a given callable
     * @param callable $keyResolver
     * @return static[]
     */
    public function groupBy(callable $keyResolver): array
    {
        $result = [];
        foreach ($this->elements as $element) {
            $key = $keyResolver($element);
            if (!isset($result[$key])) {
                $result[$key] = new static($this->idMapper);
            }
            $result[$key]->add($element);
        }

        return $result;
    }

    /**
     * Returns collection size.
     * @return int
     */
    public function count(): int
    {
        return count($this->elements);
    }

    /**
     * Clear collection
     * @return $this
     */
    public function clear(): self
    {
        $this->elements = [];
        return $this;
    }

    /**
     * @phpstan-pure
     * Merges current collection with a given collection. Returns new collection
     * @param self $collection
     * @return self
     */
    public function merge(self $collection): self
    {
        return (clone $collection)->addArray($this->elements);
    }

    /**
     * @phpstan-pure
     * Slices collection. Returns new collection as a result
     * @param int $offset
     * @param int|null $limit
     * @return static
     */
    public function slice(int $offset, ?int $limit = null): self
    {
        if ($offset === 0 && empty($limit)) {
            return $this;
        }

        $collection = new static($this->idMapper);
        $collection->addArray(array_slice($this->elements, $offset, $limit, true));

        return $collection;
    }

    /**
     * Cast collection to array
     * @return CollectionEntity[]
     */
    public function toArray(): array
    {
        return $this->elements;
    }

    /**
     * Return collection keys
     * @return array<mixed>
     */
    public function keys(): array
    {
        return array_keys($this->elements);
    }
}

安装

使用Composer将此包作为依赖项安装。

composer require nkopylov/php-typed-collections

用法

vendor/bin/typed-collections generate <--class=> <--generated-class-name=> <--path=> <--namespace=> <--template=> <--parent-class=> <--interfaces=> <--traits=>

generate命令生成一个新的静态类型集合,并将其放在可收集的PHP类旁边。

命令参数

  • --class - 必须参数。包含可收集实体的完整类名。
  • --generated-class-name - 默认集合类名为Collection。如果您想重新定义此名称,请使用此参数指定类的名称。
  • --namespace - 默认情况下,集合将创建在可收集类的相同命名空间中。如果您想重新定义命名空间,请使用此参数指定完整的命名空间名称。
  • --path - 默认情况下,集合将放置在可收集类旁边的文件系统中。如果您更改了命名空间或需要将此集合放置在其他位置,请使用此参数指定新路径。
  • --template - 默认模板已设置。它包含默认方法,并支持\Iterable\ArrayAccess接口。如果您想设置自己的模板,请使用此参数。有关示例,请参阅src/templates/collection.template
  • --parent-class - 如果您想使生成的集合扩展某个类,请使用此参数。
  • --interfaces - 如果您需要生成的集合实现某些接口,请使用此参数。为每个接口提供完整名称,用逗号分隔接口。
  • --traits - 如果您需要生成的集合使用某些特性,请使用此参数。提供完整特性名称列表,用逗号分隔。

示例

vendor/bin/typed-collections generate --class=\MyEntity

此命令将生成一个名为\MyEntityCollection的集合,并将其放置在\MyEntity类旁边。

键映射

php-typed-collections支持三种为集合实体设置键的方法

  • 通过int自动递增自动生成键(默认)
  • 在可收集类中的getId()方法。实现\Nkopylov\PhpCollections\ObjectWithIdentifier,使生成器知道您的类支持此功能。
  • 您还可以提供自己的函数,该函数将用于键生成。有关更多信息,请参阅\Nkopylov\PhpCollections\Mappable接口。此外,测试对象\Nkopylov\Test\PhpCollections\TestObjectWithMappable将有助于您。

贡献

欢迎贡献!在向此项目贡献之前,请熟悉CONTRIBUTING.md

要开发此项目,您需要PHP 7.4或更高版本和Composer

在本地克隆此存储库后,执行以下命令

cd /path/to/repository
composer install --dev

现在,您可以开始开发了!