Add `distinctBy()`.
This commit is contained in:
parent
1ce0386a2f
commit
a89e2c8c10
|
@ -920,7 +920,39 @@ PHP_METHOD(Collection, distinct)
|
|||
|
||||
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)
|
||||
|
|
|
@ -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