Add `associateBy()` and `associateByTo()`

This commit is contained in:
CismonX 2018-03-26 19:58:40 +08:00
parent e116696a49
commit 8d62f9a288
4 changed files with 67 additions and 5 deletions

View File

@ -130,7 +130,7 @@ const zend_function_entry collection_methods[] = {
PHP_ME(Collection, associate, transform_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, associateTo, destination_transform_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, associateBy, associate_by_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, associateByTo, associate_by_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, associateByTo, associate_by_to_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, average, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Collection, containsAll, other_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, containsKey, key_arginfo, ZEND_ACC_PUBLIC)

View File

@ -212,12 +212,54 @@ PHP_METHOD(Collection, associateTo)
PHP_METHOD(Collection, associateBy)
{
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
INIT_FCI();
zval* current = COLLECTION_FETCH_EX();
ARRAY_NEW_EX(new_collection, current);
ZEND_HASH_FOREACH_BUCKET(Z_ARRVAL_P(current), Bucket* bucket)
ZVAL_COPY_VALUE(&params[0], &bucket->val);
CALLBACK_PASS_PAIR(bucket);
zend_call_function(&fci, &fcc);
zval_ptr_dtor(&params[0]);
if (Z_TYPE(retval) == IS_LONG)
zend_hash_index_add(new_collection, Z_LVAL(retval), &bucket->val);
else if (Z_TYPE(retval) == IS_STRING)
zend_hash_add(new_collection, Z_STR(retval), &bucket->val);
else
ERR_BAD_CALLBACK_RETVAL();
ZEND_HASH_FOREACH_END();
RETVAL_NEW_COLLECTION(new_collection);
}
PHP_METHOD(Collection, associateByTo)
{
zend_fcall_info fci;
zend_fcall_info_cache fcc;
zval* dest;
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_OBJECT_OF_CLASS(dest, collections_collection_ce)
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
INIT_FCI();
zval* current = COLLECTION_FETCH_EX();
zend_array* dest_arr = Z_ARRVAL_P(COLLECTION_FETCH(dest));
ZEND_HASH_FOREACH_BUCKET(Z_ARRVAL_P(current), Bucket* bucket)
ZVAL_COPY_VALUE(&params[0], &bucket->val);
CALLBACK_PASS_PAIR(bucket);
zend_call_function(&fci, &fcc);
zval_ptr_dtor(&params[0]);
if (Z_TYPE(retval) == IS_LONG)
zend_hash_index_add(dest_arr, Z_LVAL(retval), &bucket->val);
else if (Z_TYPE(retval) == IS_STRING)
zend_hash_add(dest_arr, Z_STR(retval), &bucket->val);
else
ERR_BAD_CALLBACK_RETVAL();
ZEND_HASH_FOREACH_END();
RETVAL_ZVAL(dest, 1, 0);
}
PHP_METHOD(Collection, average)

View File

@ -7,14 +7,14 @@ $collection = Collection::init($array)
->associate(function ($value, $key) {
return new Pair($value, $key);
});
if ($collection->toArray() != array_flip($array))
echo 'Collection::associate() failed.', PHP_EOL;
$array1 = ['baz' => 1];
$collection1 = Collection::init($array1);
$array2 = $collection->associateTo($collection1,
function ($value, $key) {
return new Pair($key, $value);
})->toArray();
if ($collection->toArray() != array_flip($array))
echo 'Collection::associate() failed.', PHP_EOL;
if ($array2 != $array1 + array_flip($array) || $collection1->toArray() != $array2)
echo 'Collection::associateTo() failed.', PHP_EOL;
?>

View File

@ -0,0 +1,20 @@
--TEST--
Test Collection::associateBy() and Collection::associateByTo().
--FILE--
<?php
$array = ['a' => 'b', 'cd' => 'd', 'fgh' => 'i'];
$collection = Collection::init($array)
->associateBy(function ($value, $key) {
return strlen($key) - 1;
});
if ($collection->toArray() != array_values($array))
echo 'Collection::associateBy() failed.', PHP_EOL;
$array1 = ['foo' => 'bar'];
$collection1 = Collection::init($array1);
$array2 = $collection->associateByTo($collection1, function ($value, $key) {
return $key;
})->toArray();
if ($array2 != $array1 + $collection->toArray() || $collection1->toArray() != $array2)
echo 'Collection::associateTo() failed.', PHP_EOL;
?>
--EXPECT--