Skip to content

Repository files navigation

Tuck\Sort

Build StatusLatest Stable VersionTotal DownloadsLicense

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

useTuck\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, 3var_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 = newArrayIterator([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.

About

Syntatic sugar for sorting in PHP

Resources

Stars

114 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - rosstuck/sort: Syntatic sugar for sorting in PHP · GitHub
Skip to content

Repository files navigation

Tuck\Sort

Build StatusLatest Stable VersionTotal DownloadsLicense

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

useTuck\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, 3var_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 = newArrayIterator([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.

About

Syntatic sugar for sorting in PHP

Resources

Stars

114 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - rosstuck/sort: Syntatic sugar for sorting in PHP · GitHub
Skip to content

Repository files navigation

Tuck\Sort

Build StatusLatest Stable VersionTotal DownloadsLicense

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

useTuck\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, 3var_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 = newArrayIterator([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.

About

Syntatic sugar for sorting in PHP

Resources

Stars

114 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - rosstuck/sort: Syntatic sugar for sorting in PHP · GitHub
Skip to content

Repository files navigation

Tuck\Sort

Build StatusLatest Stable VersionTotal DownloadsLicense

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

useTuck\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, 3var_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 = newArrayIterator([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.

About

Syntatic sugar for sorting in PHP

Resources

Stars

114 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - rosstuck/sort: Syntatic sugar for sorting in PHP · GitHub
Skip to content

Repository files navigation

Tuck\Sort

Build StatusLatest Stable VersionTotal DownloadsLicense

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

useTuck\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, 3var_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 = newArrayIterator([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.

About

Syntatic sugar for sorting in PHP

Resources

Stars

114 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - rosstuck/sort: Syntatic sugar for sorting in PHP · GitHub
Skip to content

Repository files navigation

Tuck\Sort

Build StatusLatest Stable VersionTotal DownloadsLicense

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

useTuck\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, 3var_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 = newArrayIterator([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.

About

Syntatic sugar for sorting in PHP

Resources

Stars

114 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - rosstuck/sort: Syntatic sugar for sorting in PHP · GitHub
Skip to content

Repository files navigation

Tuck\Sort

Build StatusLatest Stable VersionTotal DownloadsLicense

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

useTuck\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, 3var_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 = newArrayIterator([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.

About

Syntatic sugar for sorting in PHP

Resources

Stars

114 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - rosstuck/sort: Syntatic sugar for sorting in PHP · GitHub
Skip to content

Repository files navigation

Tuck\Sort

Build StatusLatest Stable VersionTotal DownloadsLicense

Syntactic sugar for PHP's built in sorting.

Examples

Basic sorting functions

useTuck\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, 3var_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 = newArrayIterator([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.

About

Syntatic sugar for sorting in PHP

Resources

Stars

114 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages