khalyomede/reorder-before-after

在数组中重新排列一个项目,在另一个项目之前或之后。

0.4.0 2023-11-28 20:43 UTC

This package is auto-updated.

Last update: 2024-09-28 22:34:11 UTC


README

在数组中重新排列一个项目,在另一个项目之前或之后。

摘要

关于

我创建了一个网络应用程序,我的用户可以在另一个项目之前或之后重新排序。

我没有找到任何包来完成我所寻找的功能,由于我在应用程序的多个地方使用它,我认为将其开源可以帮助简化其他开发者的生活!

特性

  • 可以在项目列表中重新排序项目,在另一个项目之前或之后。
  • 通过重写从最小索引开始的所有项目的索引,系统地“自我修复”项目顺序。

要求

  • PHP >= 8.1
  • Composer

安装

在您的终端中,在项目文件夹的根目录下运行

composer require khalyomede/reorder-before-after

示例

1. 将一个项目移动到另一个项目之前

在这个例子中,我们将我们的书移动到桌子之前。

use Khalyomede\ReorderBeforeAfter\Item;
use Khalyomede\ReorderBeforeAfter\Listing;
use Khalyomede\ReorderBeforeAfter\Placement;

$listing = new Listing();

$listing->push(new Item("bag", 1));
$listing->push(new Item("chair", 2));
$listing->push(new Item("table", 3));
$listing->push(new Item("book", 4));

$listing->reorder("book", Placement::Before, "table");

assert($listing->find("bag")->order === 1);
assert($listing->find("chair")->order === 2);
assert($listing->find("book")->order === 3);
assert($listing->find("table")->order === 4);

2. 从任何类型创建项目列表

在这个例子中,我们将看到我们可以创建任何内容的列表,包括对象。

use Khalyomede\ReorderBeforeAfter\Item;
use Khalyomede\ReorderBeforeAfter\Listing;

final readonly class Product
{
    public function __construct(
        public string $name,
        public int $quantity,
        public float $unitPrice,
    ) {}
}

$bags = new Product("bag", 15, 149.99);
$tables = new Product("table", 4, 89.99);
$chairs = new Product("chairs", 1, 399.99);

$listing = new Listing();

$listing->push(new Item($bags, 1));
$listing->push(new Item($tables, 2));
$listing->push(new Item($chairs, 3));

3. 根据其值查找项目

在这个例子中,我们将看到我们可以根据其“值”找到项目(创建新Item实例时的第一个参数)。

use Khalyomede\ReorderBeforeAfter\Item;
use Khalyomede\ReorderBeforeAfter\Listing;
use Khalyomede\ReorderBeforeAfter\Placement;

$listing = new Listing();

$listing->push(new Item("bag", 1));
$listing->push(new Item("chair", 2));
$listing->push(new Item("table", 3));
$listing->push(new Item("book", 4));

echo $listing->find("bag"); // Item(value: "bag", order: 1)

如果该方法找不到匹配值的项,将抛出ItemNotFoundException

您还可以通过可以使用===检查的任何内容进行搜索,包括对象。

use Khalyomede\ReorderBeforeAfter\Item;
use Khalyomede\ReorderBeforeAfter\Listing;
use Khalyomede\ReorderBeforeAfter\Placement;

final readonly class Product
{
    public function __construct(
        public string $name,
        public int $quantity,
        public float $unitPrice,
    ) {}
}

$bags = new Product("bag", 15, 149.99);
$tables = new Product("table", 4, 89.99);
$chairs = new Product("chairs", 1, 399.99);

$listing = new Listing();

$listing->push(new Item($bags, 1));
$listing->push(new Item($tables, 2));
$listing->push(new Item($chairs, 3));

echo $listing->find($bags); // Item(value: Product(name: "bag", quantity: 15, unitPrice: 149.99), order: 1)

4. 从数组创建列表

在这个例子中,我们将从数组而不是手动推送项目创建列表。

use Khalyomede\ReorderBeforeAfter\Listing;

$listing = Listing::from([
    new Item("bag", 1),
    new Item("chair", 2),
    new Item("book", 3),
    new Item("table", 4),
]);

$listing->reorder("bag", Placement::After, "book");

assert($listing->find("bag")->order === 3);

5. 从列表获取所有项目

在这个例子中,我们将从列表获取所有项目。如果您想要在重新排序项目后执行一些任务,这很有用。

use Khalyomede\ReorderBeforeAfter\Listing;

$listing = Listing::from([
    new Item("bag", 1),
    new Item("chair", 2),
    new Item("book", 3),
    new Item("table", 4),
]);

$products = $listing->all();

foreach ($products as $product) {
    echo $product; // "bag" or "chair" or "book" or "table"
}

6. 使用回调在值上应用排序

在这个例子中,我们将指导列表如何设置我们的值上的顺序。如果您拥有的值是包含其顺序的对象,这很有用。这可以节省您在所有对象上再次循环。

此示例包含一个假设的Product Eloquent模型。

use App\Models\Product;
use Khalyomede\ReorderBeforeAfter\Listing;

$items = Product::all()->map(fn (Product $product): Item => new Item($product, $product->order));
$listing = Listing::from($items);

$listing->applyWith(function (Item $item): void {
    $item->value->order = $item->order;
    $item->value->save();
});

7. 从值创建列表并指定如何使用回调检索排序

在这个例子中,我们将看到如何从值数组创建列表,并使用第二个参数指定如何从这些值获取排序。

如果您有已经持有自己顺序的对象,并且不想从它们中循环并手动创建Item,这很有用。

use App\Models\Product;
use Khalyomede\ReorderBeforeAfter\Listing;

$products = Product::all();
$listing = Listing::outOf($products, fn (Product $product): Item => new Item($product, $product->order));

8. 指定如何匹配项目

在这个例子中,我们将指导列表如何匹配我们的对象。如果您拥有的对象可以包含不同数据集,使得整个对象不同,但实际上它们是相等的(通过id匹配),这很有用。

此示例包含一个假设的Product Eloquent模型,其中一个可以具有更多属性(如预加载关系),使得三重相等检查无效。

use App\Models\Product;
use Khalyomede\ReorderBeforeAfter\Listing;

$listing = Listing::outOf(Product::all(), fn (Product $product): Item => new Item($product, $product->order));

$listing->matchWith(fn (Product $left, Product $right): bool => $left->id === $right->id);

// Or with the shorter Eloquent::is() method
$listing->matchWith(fn (Product $left, Product $right): bool => $left->is($right));

测试

composer run test
composer run analyse
composer run lint
composer run check
composer run updates
composer run scan

或者

composer run all