Add `containsAllKeys()` and `containsAllValues()`.
This commit is contained in:
parent
71d97cf961
commit
24a3b72049
|
@ -129,6 +129,8 @@ const zend_function_entry collection_methods[] = {
|
|||
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, containsAllKeys, other_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, containsAllValues, other_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, containsKey, contains_key_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, containsValue, element_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, copyOf, copy_of_arginfo, ZEND_ACC_PUBLIC)
|
||||
|
|
|
@ -738,22 +738,99 @@ PHP_METHOD(Collection, containsAll)
|
|||
ZEND_PARSE_PARAMETERS_END();
|
||||
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
|
||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||
ZEND_HASH_FOREACH_VAL(elements_arr, zval* element)
|
||||
equal_check_func_t eql = equal_check_func_init(element);
|
||||
int result = 0;
|
||||
ZEND_HASH_FOREACH_VAL(current, zval* val)
|
||||
result = eql(element, val);
|
||||
if (result) {
|
||||
break;
|
||||
equal_check_func_t eql = NULL;
|
||||
ZEND_HASH_FOREACH_BUCKET(elements_arr, Bucket* bucket)
|
||||
if (UNEXPECTED(eql == NULL)) {
|
||||
eql = equal_check_func_init(&bucket->val);
|
||||
}
|
||||
if (bucket->key) {
|
||||
zval* result = zend_hash_find(current, bucket->key);
|
||||
if (!result || !eql(&bucket->val, result)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
} else {
|
||||
zval* result = zend_hash_index_find(current, bucket->h);
|
||||
if (!result || !eql(&bucket->val, result)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
ZEND_HASH_FOREACH_END();
|
||||
RETVAL_TRUE;
|
||||
}
|
||||
|
||||
PHP_METHOD(Collection, containsAllKeys)
|
||||
{
|
||||
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_HASH_FOREACH_BUCKET(elements_arr, Bucket* bucket)
|
||||
if (bucket->key) {
|
||||
if (!zend_hash_exists(current, bucket->key)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
} else {
|
||||
if (!zend_hash_index_exists(current, bucket->h)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_HASH_FOREACH_END();
|
||||
if (result == 0) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
ZEND_HASH_FOREACH_END();
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
PHP_METHOD(Collection, containsAllValues)
|
||||
{
|
||||
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();
|
||||
compare_func_t cmp = NULL;
|
||||
equal_check_func_t eql = NULL;
|
||||
ZEND_HASH_FOREACH_VAL(current, zval* val)
|
||||
cmp = compare_func_init(val, 0, 0);
|
||||
eql = equal_check_func_init(val);
|
||||
break;
|
||||
ZEND_HASH_FOREACH_END();
|
||||
ARRAY_CLONE(sorted_current, current);
|
||||
zend_hash_sort(sorted_current, cmp, 1);
|
||||
ARRAY_CLONE(sorted_other, elements_arr);
|
||||
zend_hash_sort(sorted_other, cmp, 1);
|
||||
Bucket* this = NULL;
|
||||
Bucket* other = sorted_other->arData;
|
||||
Bucket* end_other = other + zend_hash_num_elements(sorted_other);
|
||||
zend_bool result = 1;
|
||||
ZEND_HASH_FOREACH_BUCKET(sorted_current, Bucket* bucket)
|
||||
if (EXPECTED(this) && eql(&bucket->val, &this->val)) {
|
||||
continue;
|
||||
}
|
||||
this = bucket;
|
||||
if (cmp(bucket, other)) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
do {
|
||||
if (UNEXPECTED(++other == end_other)) {
|
||||
goto end;
|
||||
}
|
||||
} while (eql(&(other - 1)->val, &other->val));
|
||||
ZEND_HASH_FOREACH_END();
|
||||
result = 0;
|
||||
do {
|
||||
if (UNEXPECTED(++other == end_other)) {
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
} while (eql(&(other - 1)->val, &other->val));
|
||||
end:
|
||||
zend_array_destroy(sorted_current);
|
||||
zend_array_destroy(sorted_other);
|
||||
RETVAL_BOOL(result);
|
||||
}
|
||||
|
||||
PHP_METHOD(Collection, containsKey)
|
||||
{
|
||||
zval* key;
|
||||
|
@ -1546,18 +1623,18 @@ PHP_METHOD(Collection, intersect)
|
|||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||
ARRAY_NEW(intersected, 8);
|
||||
equal_check_func_t eql = NULL;
|
||||
ZEND_HASH_FOREACH_BUCKET(elements_arr, Bucket* bucket)
|
||||
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
|
||||
if (UNEXPECTED(eql == NULL)) {
|
||||
eql = equal_check_func_init(&bucket->val);
|
||||
}
|
||||
if (bucket->key) {
|
||||
zval* result = zend_hash_find(current, bucket->key);
|
||||
zval* result = zend_hash_find(elements_arr, bucket->key);
|
||||
if (result && eql(&bucket->val, result)) {
|
||||
zend_hash_add(intersected, bucket->key, result);
|
||||
Z_TRY_ADDREF_P(result);
|
||||
}
|
||||
} else {
|
||||
zval* result = zend_hash_index_find(current, bucket->h);
|
||||
zval* result = zend_hash_index_find(elements_arr, bucket->h);
|
||||
if (result && eql(&bucket->val, result)) {
|
||||
zend_hash_index_add(intersected, bucket->h, result);
|
||||
Z_TRY_ADDREF_P(result);
|
||||
|
|
|
@ -17,6 +17,8 @@ PHP_METHOD(Collection, associateBy);
|
|||
PHP_METHOD(Collection, associateByTo);
|
||||
PHP_METHOD(Collection, average);
|
||||
PHP_METHOD(Collection, containsAll);
|
||||
PHP_METHOD(Collection, containsAllKeys);
|
||||
PHP_METHOD(Collection, containsAllValues);
|
||||
PHP_METHOD(Collection, containsKey);
|
||||
PHP_METHOD(Collection, containsValue);
|
||||
PHP_METHOD(Collection, copyOf);
|
||||
|
|
|
@ -93,13 +93,29 @@ class Collection implements ArrayAccess, Countable
|
|||
function average() {}
|
||||
|
||||
/**
|
||||
* Checks if all elements in the specified collection are contained in this collection.
|
||||
* Checks if all key-value pairs in the specified collection are contained in this collection.
|
||||
*
|
||||
* @param array|Collection $other
|
||||
* @return bool
|
||||
*/
|
||||
function containsAll($other) {}
|
||||
|
||||
/**
|
||||
* Checks if all keys in the specified collection are contained in this collection.
|
||||
*
|
||||
* @param array|Collection $other
|
||||
* @return bool
|
||||
*/
|
||||
function containsAllKeys($other) {}
|
||||
|
||||
/**
|
||||
* Checks if all values in the specified collection are contained in this collection.
|
||||
*
|
||||
* @param array|Collection $other
|
||||
* @return bool
|
||||
*/
|
||||
function containsAllValues($other) {}
|
||||
|
||||
/**
|
||||
* Checks if the collection contains the given key.
|
||||
*
|
||||
|
|
|
@ -1,12 +1,38 @@
|
|||
--TEST--
|
||||
Test Collection::containsAll().
|
||||
Test Collection::containsAll(), Collection::containsAllKeys(), Collection::containsAllValues().
|
||||
--FILE--
|
||||
<?php
|
||||
$array = [[], 1, 't'];
|
||||
$array1 = [2, ['t'], 5];
|
||||
$collection = Collection::init([1, 2, 't', [], 5]);
|
||||
if (!$collection->containsAll($array) || $collection->containsAll($array1)) {
|
||||
$collection = Collection::init([
|
||||
'a' => 'b',
|
||||
'c' => 'd',
|
||||
'e' => 'f'
|
||||
]);
|
||||
$collection1 = Collection::init([
|
||||
'a' => 'j',
|
||||
'c' => 'f',
|
||||
'e' => 'b'
|
||||
]);
|
||||
$collection2 = Collection::init([
|
||||
'a' => 'b',
|
||||
'e' => 'f'
|
||||
]);
|
||||
if (!$collection->containsAll($collection2) ||
|
||||
$collection2->containsAll($collection) ||
|
||||
$collection->containsAll($collection1)
|
||||
) {
|
||||
echo 'Collection::containsAll() failed.', PHP_EOL;
|
||||
}
|
||||
if (!$collection1->containsAllKeys($collection2) ||
|
||||
!$collection->containsAllKeys($collection1) ||
|
||||
$collection2->containsAllKeys($collection1)
|
||||
) {
|
||||
echo 'Collection::containsAllKeys() failed.', PHP_EOL;
|
||||
}
|
||||
if (!$collection->containsAllValues($collection2) ||
|
||||
!$collection1->containsAllValues($collection2) ||
|
||||
$collection->containsAllValues($collection1)
|
||||
) {
|
||||
echo 'Collection::containsAllValues() failed.', PHP_EOL;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
|
|
Reference in New Issue