diff --git a/src/collections_methods.c b/src/collections_methods.c index 1990ea2..068d728 100644 --- a/src/collections_methods.c +++ b/src/collections_methods.c @@ -1641,7 +1641,53 @@ PHP_METHOD(Collection, groupBy) PHP_METHOD(Collection, groupByTo) { - + zval* dest; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(dest, collections_collection_ce) + Z_PARAM_FUNC(fci, fcc) + ZEND_PARSE_PARAMETERS_END(); + zend_array* current = COLLECTION_FETCH_CURRENT(); + zend_array* dest_arr = COLLECTION_FETCH(dest); + SEPARATE_COLLECTION(dest_arr, dest); + zend_bool packed = HT_IS_PACKED(current); + INIT_FCI(&fci, 2); + ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket) + CALLBACK_KEYVAL_INVOKE(params, bucket); + zval* key; + zval* value; + if (IS_PAIR(retval)) + { + key = PAIR_FIRST(Z_OBJ(retval)); + value = PAIR_SECOND(Z_OBJ(retval)); + } + else + { + key = &retval; + value = &bucket->val; + } + Z_TRY_ADDREF_P(value); + zend_array* group = array_group_fetch(dest_arr, key); + if (UNEXPECTED(group == NULL)) + { + continue; + } + if (bucket->key) + { + zend_hash_add(group, bucket->key, value); + } + else if (packed) + { + zend_hash_next_index_insert(group, value); + } + else + { + zend_hash_index_add(group, bucket->h, value); + } + zval_ptr_dtor(&retval); + ZEND_HASH_FOREACH_END(); + RETVAL_NEW_COLLECTION(dest_arr); } PHP_METHOD(Collection, indexOf) diff --git a/tests/050-group-by.phpt b/tests/050-group-by.phpt index 3d75e04..4cffb0b 100644 --- a/tests/050-group-by.phpt +++ b/tests/050-group-by.phpt @@ -1,5 +1,5 @@ --TEST-- -Test Collection::groupBy(). +Test Collection::groupBy() and Collection::groupByTo(). --FILE-- toArray() != $array) { } $collection = Collection::init([7, 2, 9, 4, 1, 0]); -$collection1 = $collection->groupBy(function ($value, $key) { - if ($key % 2) { - return 'odd_idx'; +$collection1 = Collection::init(['foo' => 'bar']); +$collection2 = $collection->groupByTo($collection1, + function ($value, $key) { + if ($key % 2) { + return 'odd_idx'; + } + return 'even_idx'; } - return 'even_idx'; -}); +); $array = [ + 'foo' => 'bar', 'odd_idx' => [2, 4, 0], 'even_idx' => [7, 9, 1] ]; -if ($collection1->toArray() != $array) { - echo 'Collection::groupBy() failed.', PHP_EOL; +if ($collection2->toArray() != $array) { + echo 'Collection::groupByTo() failed.', PHP_EOL; } ?> --EXPECT--