webhappens/traverser

轻松遍历嵌套对象结构,无需担心递归。

v0.3.2 2024-06-26 14:29 UTC

This package is auto-updated.

Last update: 2024-09-26 15:00:32 UTC


README

tests

Traverser

轻松遍历嵌套对象结构,无需担心递归。非常适合构建菜单、导航、网站地图等!

安装

通过 composer 安装

composer require webhappens/traverser

将类导入您的命名空间

use WebHappens\Traverser\Traverser;

入门

为了让遍历器理解您的层次结构,您必须确保它可以为该层次结构中的每个类解析 "id","parent" 和 "children"。

默认情况下,它将按照该顺序查找每个这些名称的 "methods" 或 "properties"。如果您的类扩展自 Illuminate\Database\Eloquent\Model,它将自动从 getKey 方法解析 "id"。

您的类通常看起来像这样

public $id;

/**
 * @return object|null
 */
public function parent()
{
    //
}

/**
 * @return array
 */
public function children()
{
    //
}

接下来,创建遍历器类的新实例,并传入您用作遍历起点的类的实例。

$traverser = Traverser::make($current);

您现在可以调用此实例上的各种遍历方法。

$descendants = $traverser->descendants();

为了方便起见,您可能想要将其放在基类或特质中

// Within a base class or trait

public function traverser()
{
    return Traverser::make($this);
}

然后按如下方式调用它

// Within a class that extends the base class / uses the trait

$this->traverser()->descendants();

要深入了解如何使用遍历器,您应该查看测试。

自定义映射名称

如果您想为每个类重写默认的 "id"、"parent" 和 "children" 映射名称,您可以这样做。

为此,将一个包含自定义映射数组的第二个参数传递给构造函数。

$traverser = Traverser:make($current, [
    Page::class => ['id' => 'uri'],
    Post::class => ['parent' => 'category', 'children' => 'comments'],
    Comment::class => ['parent' => 'post'],
]);

如果您使用 Laravel,您可能希望将其绑定到服务容器。

// Within AppServiceProvider.php

$this->app->bind('traverser', function () {
    return \WebHappens\Traverser\Traverser::make()->maps([...]);
});

然后按如下方式解析

// Within your application code

$traverser = resolve('traverser')->current($current);

注意,您可以在不传递任何参数的情况下构造一个新的遍历器实例,并使用 mapscurrent 方法。

推断父级和子级

在大多数情况下,您的对象只会有关其 "parent" 或 "children" 的数据,而不会同时有关。因此,遍历器允许您轻松地从一个推断出另一个。

要推断父级,您应将所有可能的父级数组传递给 inferParent 方法。这些对象中的每一个都必须能够解析其自己的子级。

// Within Category.php

public function parent()
{
    return $this->traverser()->inferParent(static::all());
}

public function children()
{
    return array_merge($this->categories(), $this->posts());
}

// Within Post.php

public function category()
{
    return $this->traverser()->inferParent(Category::all());
}

要推断子级,您应将所有可能的子级数组传递给 inferChildren 方法。这些对象中的每一个都必须能够解析其自己的父级。

// Within Page.php

public function parent()
{
    // ...
    return new static($parentId);
}

public function children()
{
    return $this->traverser()->inferChildren(static::all());
}

遍历方法

$parent = $this->traverser()->parent();
$children = $this->traverser()->children();
$ancestors = $this->traverser()->ancestors();
$ancestorsAndSelf = $this->traverser()->ancestorsAndSelf();
$descendants = $this->traverser()->descendants();
$descendantsAndSelf = $this->traverser()->descendantsAndSelf();
$siblings = $this->traverser()->siblings();
$siblingsAndSelf = $this->traverser()->siblingsAndSelf();
$siblingsNext = $this->traverser()->siblingsNext();
$siblingsAfter = $this->traverser()->siblingsAfter();
$siblingsPrevious = $this->traverser()->siblingsPrevious();
$siblingsBefore = $this->traverser()->siblingsBefore();
$siblingsPosition = $this->traverser()->siblingsPosition();

鸣谢

许可证

MIT 许可证 (MIT)。有关更多信息,请参阅 许可证文件