lorenzomar/ doctrine-sortable-collections

此包最新版本(dev-master)没有提供许可信息。

Doctrine 集合库的排序函数

dev-master 2014-01-16 09:50 UTC

This package is not auto-updated.

Last update: 2024-09-23 16:12:16 UTC


README

DoctrineSortableCollections 是一个库,它为 Doctrine 的基础库添加了排序功能。借助 DoctrineSortableCollections,您将能够排序简单的列表(例如由数字、字符串、日期等组成)或复杂的列表(例如包含对象的列表,您希望根据一个或多个属性的值进行排序,或者数组数组),利用 Symfony 的 PropertyAccess 组件。

安装

可以使用 composer 安装 DoctrineSortableCollections

composer require lorenzomar/doctrine-sortable-collections

或者将其添加到 composer.json 文件中

"require": {
    "lorenzomar/doctrine-sortable-collections": "dev-master"
}

使用方法

一切的基础是 SortableArrayCollection,它扩展了 ArrayCollection 并实现了 SortableInterface,添加了一个 sort 方法,允许您排序集合。sort 方法所需的唯一参数是 ComparerInterface 的一个实例。

比较器是对象,它们的唯一任务是比较两个元素并返回

  • -1 如果第一个元素大于第二个元素
  • 0 如果两个元素相同
  • 1 如果第一个元素小于第二个元素

目前有 3 个比较器

  1. NumericalComparer,能够比较任何格式的两个数值(整数、浮点数、十六进制、二进制、八进制)
  2. DateTimeComparer,能够比较两个 DateTime 对象
  3. CallbackComparer,这是最通用的一个。它使用用户提供的回调函数来比较两个元素。如果没有其他比较器适用,可以退而求其次使用这个

库提供了一个比较器的基础类,Comparer,它实现了选择排序方向(升序或降序)的功能。默认为升序,但可以通过构造函数或使用 setDirection 方法传递方向。对于复杂列表的排序,将 PropertyAccessorInterfacePropertyPathInterface 的实例传递给 Comparer,这样比较器就可以访问执行比较所需的数据。(可以在此处查阅 PropertyAccess 的文档。)

排序简单列表

以下示例将展示如何对由简单元素(数字、日期、字符串)组成的列表进行排序。

此示例展示了如何使用 NumericalComparer 对数字列表进行排序

use DoctrineSortableCollections\SortableArrayCollection;
use DoctrineSortableCollections\Comparer\Comparer;
use DoctrineSortableCollections\Comparer\NumericalComparer;

$collection = new SortableArrayCollection(array(3, 1, 2));
$ascComparer = new NumericalComparer();
$descComparer = new NumericalComparer(Comparer::DESC);

$collection->sort($ascComparer); // array(1, 2, 3)
$collection->sort($descComparer); // array(3, 2, 1)

此示例展示了如何使用 DateTimeComparer 对日期列表进行排序

use DoctrineSortableCollections\SortableArrayCollection;
use DoctrineSortableCollections\Comparer\Comparer;
use DoctrineSortableCollections\Comparer\DateTimeComparer;

$collection = new SortableArrayCollection(array(
    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-02 11:00:00');
    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-03 11:00:00');
    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-01 11:00:00');
));

$ascComparer = new DateTimeComparer();
$descComparer = new DateTimeComparer(Comparer::DESC);

/**
 * array(
 *    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-01 11:00:00');
 *    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-02 11:00:00');
 *    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-03 11:00:00');
 * )
 */
$collection->sort($ascComparer);

/**
 * array(
 *    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-03 11:00:00');
 *    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-02 11:00:00');
 *    \DateTime::createFromFormat('Y-m-d H:i:s', '2013-10-01 11:00:00');
 * )
 */
$collection->sort($descComparer);

此示例展示了如何使用 CallbackComparer 对字符串列表进行排序

use DoctrineSortableCollections\SortableArrayCollection;
use DoctrineSortableCollections\Comparer\Comparer;
use DoctrineSortableCollections\Comparer\CallbackComparer;

$collection = new SortableArrayCollection(array(
    'stringa 2',
    'stringa 1',
    'stringa 3'
));

$callback = function($e1, $e2, $collection) {
    $res = strcmp($e1, $e2);

    if ($res < 0) {
        return ($collection->isAsc()) ? $res : 1;
    } elseif ($res === 0) {
        return $res;
    } else {
        return ($collection->isAsc()) ? $res : -1;
    }
};
$ascComparer = new CallbackComparer($callback);
$descComparer = new CallbackComparer($callback, Comparer::DESC);

/**
 * array(
 *    'stringa 1',
 *    'stringa 2',
 *    'stringa 3'
 * )
 */
$collection->sort($ascComparer);

/**
 * array(
 *    'stringa 3',
 *    'stringa 2',
 *    'stringa 1'
 * )
 */
$collection->sort($descComparer);

排序复杂列表

如前所述,复杂列表的排序利用了 Symfony 的 PropertyAccess 组件。以下是一个示例列表,其中每个元素都是一个包含有关假设用户信息的数组的对象;我们想要根据用户的某些属性对这些用户进行排序。

use DoctrineSortableCollections\SortableArrayCollection;
use DoctrineSortableCollections\Comparer\DateTimeComparer;
use DoctrineSortableCollections\Comparer\NumericalComparer;
use Symfony\Component\PropertyAccess\PropertyAccessor;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\PropertyAccess\PropertyAccess;

$users = array(
    array(
        'firstName' => 'First name 1',
        'lastName'  => 'Last name 1',
        'age'       => 22,
        'birthDate' => \DateTime::createFromFormat('Y-m-d H:i:s', '1988-07-30 00:00:01')
    ),
    array(
        'firstName' => 'First name 2',
        'lastName'  => 'Last name 2',
        'age'       => 17,
        'birthDate' => \DateTime::createFromFormat('Y-m-d H:i:s', '1992-01-06 14:54:23')
    ),
    array(
        'firstName' => 'First name 3',
        'lastName'  => 'Last name 3',
        'age'       => 56,
        'birthDate' => \DateTime::createFromFormat('Y-m-d H:i:s', '1958-03-19 22:00:00')
    ),
    array(
        'firstName' => 'First name 4',
        'lastName'  => 'Last name 4',
        'age'       => 30,
        'birthDate' => \DateTime::createFromFormat('Y-m-d H:i:s', '1977-11-30 10:45:00')
    ),
    array(
        'firstName' => 'First name 5',
        'lastName'  => 'Last name 5',
        'age'       => 11,
        'birthDate' => \DateTime::createFromFormat('Y-m-d H:i:s', '2000-10-13 15:35:01')
    )
);

$collection = new SortableArrayCollection($users);

$propertyAccessor = PropertyAccess::createPropertyAccessor();

// Ordina la lista sulla base del campo 'age'
$propertyPath = new PropertyPath('[age]');
$comparer = new NumericalComparer();
$comparer->setPropertyAccessor($propertyAccessor);
$comparer->setPropertyPath($propertyPath);

$collection->sort($comparer);

// Ordina la lista sulla base del campo 'birthDate'
$propertyPath = new PropertyPath('[birthDate]');
$comparer = new DateTimeComparer();
$comparer->setPropertyAccessor($propertyAccessor);
$comparer->setPropertyPath($propertyPath);

$collection->sort($comparer);

关于

作者

Lorenzo Marzullo - marzullo.lorenzo@gmail.com

许可

DoctrineSortableCollections 以 MIT 许可证发布 - 请参阅 'LICENSE' 文件获取详细信息