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, associateByTo, associate_by_to_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, average, NULL, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, average, NULL, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, containsAll, other_arginfo, 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, containsKey, contains_key_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, containsValue, element_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, containsValue, element_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, copyOf, copy_of_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();
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
|
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
|
||||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||||
ZEND_HASH_FOREACH_VAL(elements_arr, zval* element)
|
equal_check_func_t eql = NULL;
|
||||||
equal_check_func_t eql = equal_check_func_init(element);
|
ZEND_HASH_FOREACH_BUCKET(elements_arr, Bucket* bucket)
|
||||||
int result = 0;
|
if (UNEXPECTED(eql == NULL)) {
|
||||||
ZEND_HASH_FOREACH_VAL(current, zval* val)
|
eql = equal_check_func_init(&bucket->val);
|
||||||
result = eql(element, val);
|
}
|
||||||
if (result) {
|
if (bucket->key) {
|
||||||
break;
|
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();
|
ZEND_HASH_FOREACH_END();
|
||||||
RETURN_TRUE;
|
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)
|
PHP_METHOD(Collection, containsKey)
|
||||||
{
|
{
|
||||||
zval* key;
|
zval* key;
|
||||||
|
@ -1546,18 +1623,18 @@ PHP_METHOD(Collection, intersect)
|
||||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||||
ARRAY_NEW(intersected, 8);
|
ARRAY_NEW(intersected, 8);
|
||||||
equal_check_func_t eql = NULL;
|
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)) {
|
if (UNEXPECTED(eql == NULL)) {
|
||||||
eql = equal_check_func_init(&bucket->val);
|
eql = equal_check_func_init(&bucket->val);
|
||||||
}
|
}
|
||||||
if (bucket->key) {
|
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)) {
|
if (result && eql(&bucket->val, result)) {
|
||||||
zend_hash_add(intersected, bucket->key, result);
|
zend_hash_add(intersected, bucket->key, result);
|
||||||
Z_TRY_ADDREF_P(result);
|
Z_TRY_ADDREF_P(result);
|
||||||
}
|
}
|
||||||
} else {
|
} 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)) {
|
if (result && eql(&bucket->val, result)) {
|
||||||
zend_hash_index_add(intersected, bucket->h, result);
|
zend_hash_index_add(intersected, bucket->h, result);
|
||||||
Z_TRY_ADDREF_P(result);
|
Z_TRY_ADDREF_P(result);
|
||||||
|
|
|
@ -17,6 +17,8 @@ PHP_METHOD(Collection, associateBy);
|
||||||
PHP_METHOD(Collection, associateByTo);
|
PHP_METHOD(Collection, associateByTo);
|
||||||
PHP_METHOD(Collection, average);
|
PHP_METHOD(Collection, average);
|
||||||
PHP_METHOD(Collection, containsAll);
|
PHP_METHOD(Collection, containsAll);
|
||||||
|
PHP_METHOD(Collection, containsAllKeys);
|
||||||
|
PHP_METHOD(Collection, containsAllValues);
|
||||||
PHP_METHOD(Collection, containsKey);
|
PHP_METHOD(Collection, containsKey);
|
||||||
PHP_METHOD(Collection, containsValue);
|
PHP_METHOD(Collection, containsValue);
|
||||||
PHP_METHOD(Collection, copyOf);
|
PHP_METHOD(Collection, copyOf);
|
||||||
|
|
|
@ -93,13 +93,29 @@ class Collection implements ArrayAccess, Countable
|
||||||
function average() {}
|
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
|
* @param array|Collection $other
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
function containsAll($other) {}
|
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.
|
* Checks if the collection contains the given key.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,12 +1,38 @@
|
||||||
--TEST--
|
--TEST--
|
||||||
Test Collection::containsAll().
|
Test Collection::containsAll(), Collection::containsAllKeys(), Collection::containsAllValues().
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$array = [[], 1, 't'];
|
$collection = Collection::init([
|
||||||
$array1 = [2, ['t'], 5];
|
'a' => 'b',
|
||||||
$collection = Collection::init([1, 2, 't', [], 5]);
|
'c' => 'd',
|
||||||
if (!$collection->containsAll($array) || $collection->containsAll($array1)) {
|
'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;
|
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--
|
--EXPECT--
|
||||||
|
|
Reference in New Issue