Add `intersect()` and `intersectKeys()`.

This commit is contained in:
CismonX 2018-09-03 19:34:58 +08:00
parent 81be8bd83a
commit 11ba227653
5 changed files with 124 additions and 3 deletions

View File

@ -160,6 +160,8 @@ const zend_function_entry collection_methods[] = {
PHP_ME(Collection, indexOfLast, predicate_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, init, elements_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Collection, intersect, other_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, intersectKeys, other_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, intersectValues, other_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, isEmpty, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Collection, isNotEmpty, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Collection, keys, NULL, ZEND_ACC_PUBLIC)

View File

@ -1781,7 +1781,74 @@ PHP_METHOD(Collection, init)
PHP_METHOD(Collection, intersect)
{
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_NEW(intersected, 8);
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))
{
zend_hash_add(intersected, bucket->key, result);
Z_TRY_ADDREF_P(result);
}
}
else
{
zval* result = zend_hash_index_find(current, bucket->h);
if (result && eql(&bucket->val, result))
{
zend_hash_index_add(intersected, bucket->h, result);
Z_TRY_ADDREF_P(result);
}
}
ZEND_HASH_FOREACH_END();
RETVAL_NEW_COLLECTION(intersected);
}
PHP_METHOD(Collection, intersectKeys)
{
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_NEW(intersected, 8);
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
if (bucket->key)
{
if (zend_hash_exists(elements_arr, bucket->key))
{
zend_hash_add(intersected, bucket->key, &bucket->val);
Z_TRY_ADDREF(bucket->val);
}
}
else
{
if (zend_hash_index_exists(elements_arr, bucket->h))
{
zend_hash_index_add(intersected, bucket->h, &bucket->val);
Z_TRY_ADDREF(bucket->val);
}
}
ZEND_HASH_FOREACH_END();
RETVAL_NEW_COLLECTION(intersected);
}
PHP_METHOD(Collection, intersectValues)
{
}
PHP_METHOD(Collection, isEmpty)

View File

@ -48,6 +48,8 @@ PHP_METHOD(Collection, indexOfFirst);
PHP_METHOD(Collection, indexOfLast);
PHP_METHOD(Collection, init);
PHP_METHOD(Collection, intersect);
PHP_METHOD(Collection, intersectKeys);
PHP_METHOD(Collection, intersectValues);
PHP_METHOD(Collection, isEmpty);
PHP_METHOD(Collection, isNotEmpty);
PHP_METHOD(Collection, keys);

View File

@ -373,13 +373,34 @@ class Collection implements ArrayAccess, Countable
static function init($elements) {}
/**
* Returns a collection containing all elements that are contained by both this collection and the
* specified collection.
* Returns a collection containing all key-value pairs that are contained by both this collection
* and the specified collection.
*
* @param array|Collection $other
* @return Collection
*/
function intersect($other) {}
/**
* Returns a collection containing all elements with keys contained by both this collection
* and the specified collection. Values are that of the original collection.
*
* @param array|Collection $other
* @return Collection
*/
function intersectKeys($other) {}
/**
* Returns a collection containing all elements with values contained by both this collection
* and the specified collection. Keys are that of the original collection.
*
* Duplicate values will be removed.
*
* @param array|Collection $other
* @return Collection
*/
function intersectValues($other) {}
/**
* Returns true if the collection is empty.
*
@ -389,6 +410,8 @@ class Collection implements ArrayAccess, Countable
/**
* Returns true if the collection is not empty.
*
* @return bool
*/
function isNotEmpty() {}

View File

@ -0,0 +1,27 @@
--TEST--
Test Collection::intersect() and Collection::intersectKeys().
--FILE--
<?php
$array = [
'a' => 'b',
'c' => 'd',
'e' => 'f'
];
$array1 = [
'a' => 'c',
'b' => strval(12),
'c' => 'd',
'g' => 'h'
];
$collection = Collection::init($array);
$intersected = array_intersect_assoc($array, $array1);
if ($collection->intersect($array1)->toArray() != $intersected) {
echo 'Collection::intersect() failed.', PHP_EOL;
}
$collection1 = Collection::init($array1);
$intersected = array_intersect_key($array, $array1);
if ($collection->intersectKeys($collection1)->toArray() != $intersected) {
echo 'Collection::intersectKeys() failed.', PHP_EOL;
}
?>
--EXPECT--