定制 tuck/sort 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

tuck/sort

Composer 安装命令:

composer require tuck/sort

包简介

Syntactic sugar for PHP's sorting

关键字:

README 文档

README

Build Status Latest Stable Version Total Downloads License

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

use Tuck\Sort\Sort;

Sort::values(['foo', 'bar', 'baz']);                    // returns ['bar', 'baz', 'foo']
Sort::keys(['x' => 'foo', 'm' => 'bar']);               // returns ['m' => 'bar', 'x' => 'foo']
Sort::natural(['img12.jpg', 'img2.jpg', 'img1.jpg']);   // returns ['img1.jpg', 'img2.jpg', 'img12.jpg']
Sort::user(
    [3, 2, 5, 6],
    function () { /* custom sorting */ }
);

Why?

This library tries to smooth out the built-in API, specifically the following issues:

PHP requires variables.

If you want to sort the result of a method, you need to assign it to an intermediate variable.

$results = $metrics->getTotals();
sort($results);

With this library, you can pass results directly:

Sort::values($metrics->getTotals());

PHP modifies in-place

Perhaps you'd prefer sort to return a modified list, rather than mutating the original. Unfortunately, the return value of sort() is a success boolean, not the reordered list.

With this library, the results are returned directly and the original list is not modified:

$x = [3, 1, 2];

var_dump(Sort::values($x)); // 1, 2, 3
var_dump($x);               // 3, 1, 2

PHP's naming is confusing

PHP's sorting functions don't always have the most intuitive names:

asort()
sort()
ksort()
natsort()
usort()
uasort()
uksort()

With this library, naming reads a little better:

Sort::values()
Sort::keys()
Sort::natural()
Sort::user()

PHP doesn't handle keys consistently

When you use sort() PHP discards the original keys. Unless you use asort(). Or natsort and natcasesort which always preserve the original keys. You get the idea.

With this library, the returned keys are reset to sequential numbers, regardless of the type of sorting.

Sort::values([3 => 'bob', 1 => 'alice']);
// returns [0 => 'alice', 1 => 'bob']

If you'd like to keep the original keys, there's a consistent parameter you can always use Sort::PRESERVE_KEYS. This selects the correct key-preserving function under the hood, so you don't have to remember it.

Sort::values([3 => 'bob', 1 => 'alice'], Sort::PRESERVE_KEYS);
// returns [1 => 'alice', 3 => 'bob']

This works for all sort functions:

Sort::values(['foo', 'bar', 'baz'], Sort::PRESERVE_KEYS);
Sort::natural(['foo', 'bar', 'baz'], Sort::PRESERVE_KEYS);
Sort::user(
    [3, 2, 5, 6],
    function () { /* custom sorting */ },
    Sort::PRESERVE_KEYS
);

Much easier to remember. If the constants are too long-winded or readable, you can also pass true to preserve the keys or false to discard them.

PHP doesn't accept iterators or generators

Built-in sorting functions work great on arrays but won't accept their Traversable brethren.

With this library, iterators and generators are automatically converted to arrays.

$x = new ArrayIterator([3, 1, 2]);
Sort::values($x); // returns [1, 2, 3]

Note this library always returns arrays, even when given a custom collection. If you'd like your custom collection to support this library, see the usort documentation below.

PHP doesn't have a shorthand for sorting by fields

When you're comparing a list of objects, you usually want to compare the same field on them repeatedly. Usually that means writing a usort function like this:

Sort::user($list, function (HighScore $a, HighScore $b) {
    return $a->getPoints() <=> $b->getPoints();
});

And that's with the PHP 7 shorthand operator helping. This library offers a slightly shorter, Scala inspired version where you only specify how to retrieve the sortable data from an element.

Sort::by($list, function (HighScore $a) {
    return $a->getPoints();
});

This also works in reverse:

Sort::byDescending($list, function (HighScore $a) {
    return $a->getPoints();
});

PHP doesn't have chained usort

There's no elegant syntax for chaining multiple sorts at once. If you wanted to sort a list of high scores, first by points, then name, then date, you'd need to write a function like:

usort(
    $unsorted,
    function (HighScore $scoreA, HighScore $scoreB) {
        $a = $scoreA->getPoints();
        $b = $scoreA->getPoints();

        if ($a == $b) {
            $a = $scoreA->getDate();
            $b = $scoreB->getDate();
        }

        if ($a == $b) {
            $a = $scoreA->getName();
            $b = $scoreB->getName();
        }

        return $a <=> $b;
    }
);

With this library, you can chain sorts like so:

Sort::chain()
    ->compare(function (HighScore $a, HighScore $b) {
        return $a->getPoints() <=> $b->getPoints();
    })
    ->compare(function (HighScore $a, HighScore $b) {
        return $a->getDate() <=> $b->getDate();
    })
    ->compare(function (HighScore $a, HighScore $b) {
        return $a->getName() <=> $b->getName();
    });

In most cases, you'll want to extract the same information from $a and $b at the same time. You might also want to sort them as ascending or descending on different factors. For both of these use cases, you can use the asc() and desc() methods.

$sortChain = Sort::chain()
    ->desc(function (HighScore $score) {
        return $score->getPoints();
    })
    ->asc(function (HighScore $score) {
        return $score->getDate();
    })
    ->asc(function (HighScore $score) {
        return $score->getName();
    });

Once you've created your sorting chain, you can apply it to keys or values. Features like Iterator support, returned values, and PRESERVE_KEY flag are all supported.

$sortChain->values(['foo', 'bar']);
$sortChain->values(['foo', 'bar'], Sort::PRESERVE_KEYS);
$sortChain->keys(['foo' => 'blah', 'bar' => 'blat']);

You can also invoke the chain itself as a comparison function:

$sortChain('steven', 'connie'); // returns -1, 0 or 1

This means you can use it with any custom collection class that supports usort:

$yourCustomCollection->usort($sortChain);

When building your sort chain, you don't have to compose all the sorting functions at once. You can attach them over time or conditionally:

$sortOrder = Sort::chain();

if ($options['sort_by_name']) {
   $sortOrder->asc(...);
}

// etc

However, if use the chain before any sorts are added, then the order is essentially random and decided by your PHP runtime (PHP 5.x vs PHP 7 vs HHVM). There's no easy way to normalize this (I've tried) but it varies based on the runtime, the number of elements in the array, the sorting algorithm used, etc. The good news is it doesn't matter if the elements are random because there was nothing worth sorting by anyways! :)

License

MIT

Contributing

PRs welcome. :) Please abide by PSR-2, use tests, and respect the Code Manifesto.

Status

Working, tested, still need to add non-functionals like docs and fancy README badges.

tuck/sort 适用场景与选型建议

tuck/sort 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 49.21k 次下载、GitHub Stars 达 114, 最近一次更新时间为 2016 年 04 月 12 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「sort」 「sorting」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 tuck/sort 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 tuck/sort 我们能提供哪些服务?
定制开发 / 二次开发

基于 tuck/sort 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 49.21k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 115
  • 点击次数: 2
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 114
  • Watchers: 8
  • Forks: 8
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2016-04-12