Add `plus()` and `union()`. Fix bug.
This commit is contained in:
parent
6ab7721d47
commit
72504b9e7d
|
@ -541,7 +541,7 @@ PHP_METHOD(Collection, addAll)
|
|||
ZEND_PARSE_PARAMETERS_END();
|
||||
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
|
||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||
zend_bool packed = HT_IS_PACKED(elements_arr);
|
||||
zend_bool packed = HT_IS_PACKED(current) && HT_IS_PACKED(elements_arr);
|
||||
SEPARATE_CURRENT_COLLECTION(current);
|
||||
ZEND_HASH_FOREACH_BUCKET(elements_arr, Bucket* bucket)
|
||||
Z_TRY_ADDREF(bucket->val);
|
||||
|
@ -2028,7 +2028,25 @@ PHP_METHOD(Collection, partition)
|
|||
|
||||
PHP_METHOD(Collection, plus)
|
||||
{
|
||||
|
||||
zval* elements;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_ZVAL(elements)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
|
||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||
ARRAY_CLONE(new_collection, current);
|
||||
zend_bool packed = HT_IS_PACKED(current) && HT_IS_PACKED(elements_arr);
|
||||
ZEND_HASH_FOREACH_BUCKET(elements_arr, Bucket* bucket)
|
||||
Z_TRY_ADDREF(bucket->val);
|
||||
if (bucket->key) {
|
||||
zend_hash_update(new_collection, bucket->key, &bucket->val);
|
||||
} else if (packed) {
|
||||
zend_hash_next_index_insert(new_collection, &bucket->val);
|
||||
} else {
|
||||
zend_hash_index_update(new_collection, bucket->h, &bucket->val);
|
||||
}
|
||||
ZEND_HASH_FOREACH_END();
|
||||
RETVAL_NEW_COLLECTION(new_collection);
|
||||
}
|
||||
|
||||
PHP_METHOD(Collection, putAll)
|
||||
|
@ -2040,7 +2058,7 @@ PHP_METHOD(Collection, putAll)
|
|||
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
|
||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||
SEPARATE_CURRENT_COLLECTION(current);
|
||||
zend_bool packed = HT_IS_PACKED(elements_arr);
|
||||
zend_bool packed = HT_IS_PACKED(current) && HT_IS_PACKED(elements_arr);
|
||||
ZEND_HASH_FOREACH_BUCKET(elements_arr, Bucket* bucket)
|
||||
Z_TRY_ADDREF(bucket->val);
|
||||
if (bucket->key) {
|
||||
|
@ -2827,7 +2845,43 @@ PHP_METHOD(Collection, toPairs)
|
|||
|
||||
PHP_METHOD(Collection, union)
|
||||
{
|
||||
|
||||
zval* elements;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_ZVAL(elements)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
|
||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||
zend_bool packed = HT_IS_PACKED(current) && HT_IS_PACKED(elements_arr);
|
||||
ARRAY_CLONE(new_collection, current);
|
||||
ZEND_HASH_FOREACH_BUCKET(elements_arr, Bucket* bucket)
|
||||
Z_TRY_ADDREF(bucket->val);
|
||||
if (bucket->key) {
|
||||
zend_hash_add(new_collection, bucket->key, &bucket->val);
|
||||
} else if (packed) {
|
||||
zend_hash_next_index_insert(new_collection, &bucket->val);
|
||||
} else {
|
||||
zend_hash_index_add(new_collection, bucket->h, &bucket->val);
|
||||
}
|
||||
ZEND_HASH_FOREACH_END();
|
||||
uint32_t num_elements = zend_hash_num_elements(new_collection);
|
||||
compare_func_t cmp = NULL;
|
||||
equal_check_func_t eql = NULL;
|
||||
Bucket* ref = (Bucket*)malloc(num_elements * sizeof(Bucket));
|
||||
uint32_t idx = 0;
|
||||
ZEND_HASH_FOREACH_BUCKET(new_collection, Bucket* bucket)
|
||||
if (UNEXPECTED(cmp == NULL)) {
|
||||
cmp = compare_func_init(&bucket->val, 0, 0);
|
||||
eql = equal_check_func_init(&bucket->val);
|
||||
}
|
||||
Bucket* dest = &ref[idx++];
|
||||
dest->key = NULL;
|
||||
dest->h = bucket - new_collection->arData;
|
||||
memcpy(&dest->val, &bucket->val, sizeof(zval));
|
||||
ZEND_HASH_FOREACH_END();
|
||||
COLLECTIONS_G(cmp) = cmp;
|
||||
array_distinct(new_collection, ref, cmp, eql);
|
||||
free(ref);
|
||||
RETVAL_NEW_COLLECTION(new_collection);
|
||||
}
|
||||
|
||||
PHP_METHOD(Collection, values)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
--TEST--
|
||||
Test Collection::putAll().
|
||||
--FILE--
|
||||
<?php
|
||||
$array = ['a' => 'foo', 'b' => 'bar'];
|
||||
$array1 = ['a' => 'b', 'c' => 'd', 'e' => 'f'];
|
||||
$collection = Collection::init($array);
|
||||
$collection->putAll($array1);
|
||||
$merged = array_merge($array, $array1);
|
||||
if ($collection->toArray() != $merged) {
|
||||
echo 'Collection::putAll() failed.', PHP_EOL;
|
||||
}
|
||||
$array2 = ['e' => 'g'];
|
||||
$collection1 = Collection::init($array2);
|
||||
if ($collection->plus($collection1)->toArray() != array_merge($merged, $array2)) {
|
||||
echo 'Collection::putAll() failed.', PHP_EOL;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
|
@ -1,13 +0,0 @@
|
|||
--TEST--
|
||||
Test Collection::putAll().
|
||||
--FILE--
|
||||
<?php
|
||||
$array = ['a' => 'foo', 'b' => 'bar'];
|
||||
$array1 = ['a' => 'b', 'c' => 'd', 'e' => 'f'];
|
||||
$collection = Collection::init($array);
|
||||
$collection->putAll($array1);
|
||||
if ($collection->toArray() != array_merge($array, $array1)) {
|
||||
echo 'Collection::putAll() failed.', PHP_EOL;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
|
@ -0,0 +1,20 @@
|
|||
--TEST--
|
||||
Test Collection::union().
|
||||
--FILE--
|
||||
<?php
|
||||
$array = [];
|
||||
for ($i = 0; $i < 50; ++$i) {
|
||||
$array[] = random_int(1, 50);
|
||||
}
|
||||
$array1 = [];
|
||||
for ($i = 0; $i < 50; ++$i) {
|
||||
$array1[] = random_int(1, 50);
|
||||
}
|
||||
$union = array_values(array_unique(array_merge($array, $array1)));
|
||||
$collection = Collection::init($array);
|
||||
$collection1 = Collection::init($array1);
|
||||
if ($collection->union($collection1)->toArray() != $union) {
|
||||
echo 'Collection::union() failed.', PHP_EOL;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
Reference in New Issue