Add `distinctBy()`.
This commit is contained in:
parent
1ce0386a2f
commit
a89e2c8c10
|
@ -920,7 +920,39 @@ PHP_METHOD(Collection, distinct)
|
||||||
|
|
||||||
PHP_METHOD(Collection, distinctBy)
|
PHP_METHOD(Collection, distinctBy)
|
||||||
{
|
{
|
||||||
|
zend_fcall_info fci;
|
||||||
|
zend_fcall_info_cache fcc;
|
||||||
|
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||||
|
Z_PARAM_FUNC(fci, fcc)
|
||||||
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||||
|
compare_func_t cmp = NULL;
|
||||||
|
equal_check_func_t eql = NULL;
|
||||||
|
uint32_t num_elements = zend_hash_num_elements(current);
|
||||||
|
Bucket* ref = (Bucket*)malloc(num_elements * sizeof(Bucket));
|
||||||
|
ARRAY_CLONE(distinct, current);
|
||||||
|
uint32_t idx = 0;
|
||||||
|
INIT_FCI(&fci, 2);
|
||||||
|
ZEND_HASH_FOREACH_BUCKET(distinct, Bucket* bucket)
|
||||||
|
CALLBACK_KEYVAL_INVOKE(params, bucket);
|
||||||
|
if (UNEXPECTED(cmp == NULL))
|
||||||
|
{
|
||||||
|
cmp = compare_func_init(&retval, 0, 0);
|
||||||
|
eql = equal_check_func_init(&retval);
|
||||||
|
}
|
||||||
|
Bucket* dest = &ref[idx++];
|
||||||
|
dest->key = NULL;
|
||||||
|
dest->h = bucket - distinct->arData;
|
||||||
|
memcpy(&dest->val, &retval, sizeof(zval));
|
||||||
|
ZEND_HASH_FOREACH_END();
|
||||||
|
COLLECTIONS_G(cmp) = cmp;
|
||||||
|
array_distinct(distinct, ref, cmp, eql);
|
||||||
|
for (idx = 0; idx < num_elements; ++idx)
|
||||||
|
{
|
||||||
|
zval_ptr_dtor(&ref[idx].val);
|
||||||
|
}
|
||||||
|
free(ref);
|
||||||
|
RETVAL_NEW_COLLECTION(distinct);
|
||||||
}
|
}
|
||||||
|
|
||||||
PHP_METHOD(Collection, drop)
|
PHP_METHOD(Collection, drop)
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
--TEST--
|
||||||
|
Test Collection::distinctBy().
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$array = [];
|
||||||
|
for ($i = 0; $i < 100; ++$i) {
|
||||||
|
$array[] = random_bytes(random_int(1, 10));
|
||||||
|
}
|
||||||
|
$get_len = function ($value) {
|
||||||
|
return strlen($value);
|
||||||
|
};
|
||||||
|
$distinct = Collection::init($array)->distinctBy($get_len)->toArray();
|
||||||
|
$array1 = [];
|
||||||
|
$distinct_idx = array_keys(array_unique(array_map($get_len, $array)));
|
||||||
|
foreach ($distinct_idx as $idx) {
|
||||||
|
$array1[] = $array[$idx];
|
||||||
|
}
|
||||||
|
if ($distinct != $array1) {
|
||||||
|
echo 'Collection::distinct() failed.', PHP_EOL;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
Reference in New Issue