Add `sortWith()` and `sortedWith()`.

This commit is contained in:
CismonX 2018-08-18 14:54:26 +08:00
parent f0cc4fda1b
commit e9e1c966d7
3 changed files with 87 additions and 4 deletions

View File

@ -2081,7 +2081,35 @@ PHP_METHOD(Collection, sortDescending)
PHP_METHOD(Collection, sortWith)
{
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
FCI_G = &fci;
FCC_G = &fcc;
zend_array* current = COLLECTION_FETCH_CURRENT();
zend_array* sorted_with = zend_array_dup(current);
ZEND_HASH_FOREACH_BUCKET(sorted_with, Bucket* bucket)
NEW_PAIR_OBJ(obj);
BUCKET_2_PAIR(obj, bucket);
ZVAL_OBJ(&bucket->val, obj);
ZEND_HASH_FOREACH_END();
zend_hash_sort(sorted_with, bucket_compare_userland, 1);
ZEND_HASH_FOREACH_VAL(sorted_with, zval* val)
zend_object* pair = Z_OBJ_P(val);
ZVAL_COPY_VALUE(val, PAIR_FETCH_SECOND(pair));
GC_DELREF(pair);
ZEND_HASH_FOREACH_END();
if (GC_REFCOUNT(current) > 1)
{
GC_DELREF(current);
}
else
{
zend_array_destroy(current);
}
COLLECTION_FETCH_CURRENT() = sorted_with;
}
PHP_METHOD(Collection, sorted)
@ -2106,7 +2134,27 @@ PHP_METHOD(Collection, sortedDescending)
PHP_METHOD(Collection, sortedWith)
{
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
FCI_G = &fci;
FCC_G = &fcc;
zend_array* current = COLLECTION_FETCH_CURRENT();
zend_array* sorted_with = zend_array_dup(current);
ZEND_HASH_FOREACH_BUCKET(sorted_with, Bucket* bucket)
NEW_PAIR_OBJ(obj);
BUCKET_2_PAIR(obj, bucket);
ZVAL_OBJ(&bucket->val, obj);
ZEND_HASH_FOREACH_END();
zend_hash_sort(sorted_with, bucket_compare_userland, 1);
ZEND_HASH_FOREACH_VAL(sorted_with, zval* val)
zend_object* pair = Z_OBJ_P(val);
ZVAL_COPY_VALUE(val, PAIR_FETCH_SECOND(pair));
GC_DELREF(pair);
ZEND_HASH_FOREACH_END();
RETVAL_NEW_COLLECTION(sorted_with);
}
PHP_METHOD(Collection, take)

View File

@ -8,10 +8,10 @@ $array = [
'e' => ['b' => 5, 'c' => 4]
];
$collection = Collection::init($array);
$by_b = function($p1, $p2) {
$by_b = function ($p1, $p2) {
return $p1->second['b'] - $p2->second['b'];
};
$by_c = function($p1, $p2) {
$by_c = function ($p1, $p2) {
return strval($p1->second['c'] - $p2->second['c']);
};
if ($collection->minWith($by_b) != $array['a'] || $collection->minWith($by_c) != $array['d'])

View File

@ -0,0 +1,35 @@
--TEST--
Test Collection::sortWith() and Collection::sortedWith().
--FILE--
<?php
$array = [
'a' => ['b' => 2, 'c' => 6],
'd' => ['b' => 3, 'c' => 1],
'e' => ['b' => 5, 'c' => 4],
'f' => ['b' => 1, 'c' => 3]
];
$collection = Collection::init($array);
$by_b = function ($p1, $p2) {
return $p1->second['b'] - $p2->second['b'];
};
$usort_by_b = function ($v1, $v2) {
return $v1['b'] - $v2['b'];
};
$sorted_by_b = $collection->sortedWith($by_b);
$array1 = $array;
usort($array1, $usort_by_b);
if ($sorted_by_b->toArray() != $array1)
echo 'Collection::sortedWith() failed.', PHP_EOL;
$by_c = function ($p1, $p2) {
return $p1->second['c'] - $p2->second['c'];
};
$usort_by_c = function ($v1, $v2) {
return $v1['c'] - $v2['c'];
};
$collection->sortWith($by_c);
$array2 = $array;
usort($array2, $usort_by_c);
if ($collection->toArray() != $array2)
echo 'Collection::sortedWith() failed.', PHP_EOL;
?>
--EXPECT--