Add `flatten()`. Remove `lastIndexOf()`.

This commit is contained in:
CismonX 2018-04-22 22:47:30 +08:00
parent 6b0bbb294f
commit f2209e019d
5 changed files with 40 additions and 26 deletions

View File

@ -166,7 +166,6 @@ const zend_function_entry collection_methods[] = {
PHP_ME(Collection, isNotEmpty, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Collection, keys, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Collection, last, predicate_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, lastIndexOf, element_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, map, transform_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, mapKeys, transform_arginfo, ZEND_ACC_PUBLIC)
PHP_ME(Collection, mapKeysTo, destination_transform_arginfo, ZEND_ACC_PUBLIC)

View File

@ -74,16 +74,17 @@
#define ERR_BAD_SIZE() PHP_COLLECTIONS_ERROR(E_WARNING, "Size must be non-negative")
#define ERR_BAD_INDEX() PHP_COLLECTIONS_ERROR(E_WARNING, "Index must be non-negative")
#define ERR_NOT_ARITHMETIC() PHP_COLLECTIONS_ERROR(E_WARNING, "Elements should be int or double")
#define ERR_SILENCED()
#define ELEMENTS_VALIDATE(elements) \
#define ELEMENTS_VALIDATE(elements, err, err_then) \
zend_array* elements##_arr; \
if (IS_COLLECTION_P(elements)) \
(elements##_arr) = COLLECTION_FETCH(elements); \
else if (UNEXPECTED(Z_TYPE_P(elements) == IS_ARRAY))\
(elements##_arr) = Z_ARRVAL_P(elements); \
else { \
ERR_BAD_ARGUMENT_TYPE(); \
return; \
err(); \
err_then; \
}
#define ARRAY_NEW(name, size) \
@ -173,7 +174,7 @@ PHP_METHOD(Collection, addAll)
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(elements)
ZEND_PARSE_PARAMETERS_END();
ELEMENTS_VALIDATE(elements);
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
zend_array* current = COLLECTION_FETCH_EX();
SEPARATE_COLLECTION_EX(current);
ZEND_HASH_FILL_PACKED(current)
@ -350,7 +351,7 @@ PHP_METHOD(Collection, containsAll)
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_ZVAL(elements)
ZEND_PARSE_PARAMETERS_END();
ELEMENTS_VALIDATE(elements);
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
zend_array* current = COLLECTION_FETCH_EX();
ZEND_HASH_FOREACH_VAL(elements_arr, zval* element)
INIT_EQUAL_CHECK_FUNC(element);
@ -719,7 +720,7 @@ PHP_METHOD(Collection, flatMap)
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
CALLBACK_KEYVAL_INVOKE(params, bucket);
zval* retval_p = &retval;
ELEMENTS_VALIDATE(retval_p);
ELEMENTS_VALIDATE(retval_p, ERR_BAD_CALLBACK_RETVAL, continue);
ZEND_HASH_FOREACH_BUCKET(retval_p_arr, Bucket* bucket)
if (Z_REFCOUNTED(bucket->val))
GC_ADDREF(Z_COUNTED(bucket->val));
@ -749,7 +750,7 @@ PHP_METHOD(Collection, flatMapTo)
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
CALLBACK_KEYVAL_INVOKE(params, bucket);
zval* retval_p = &retval;
ELEMENTS_VALIDATE(retval_p);
ELEMENTS_VALIDATE(retval_p, ERR_BAD_CALLBACK_RETVAL, continue);
ZEND_HASH_FOREACH_BUCKET(retval_p_arr, Bucket* bucket)
if (Z_REFCOUNTED(bucket->val))
GC_ADDREF(Z_COUNTED(bucket->val));
@ -765,7 +766,25 @@ PHP_METHOD(Collection, flatMapTo)
PHP_METHOD(Collection, flatten)
{
zend_array* current = COLLECTION_FETCH_EX();
ARRAY_NEW_EX(new_collection, current);
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
zval* val = &bucket->val;
ELEMENTS_VALIDATE(val, ERR_SILENCED, {
if (bucket->key)
zend_hash_add(new_collection, bucket->key, &bucket->val);
else
zend_hash_next_index_insert(new_collection, &bucket->val);
continue;
});
ZEND_HASH_FOREACH_BUCKET(val_arr, Bucket* bucket)
if (bucket->key)
zend_hash_add(new_collection, bucket->key, &bucket->val);
else
zend_hash_next_index_insert(new_collection, &bucket->val);
ZEND_HASH_FOREACH_END();
ZEND_HASH_FOREACH_END();
RETVAL_NEW_COLLECTION(new_collection);
}
PHP_METHOD(Collection, fold)
@ -821,7 +840,7 @@ PHP_METHOD(Collection, init)
Z_PARAM_ZVAL(elements)
ZEND_PARSE_PARAMETERS_END();
if (elements) {
ELEMENTS_VALIDATE(elements);
ELEMENTS_VALIDATE(elements, ERR_BAD_ARGUMENT_TYPE, return);
RETURN_NEW_COLLECTION(elements_arr);
}
ARRAY_NEW(collection, 0);
@ -874,11 +893,6 @@ PHP_METHOD(Collection, last)
RETVAL_NULL();
}
PHP_METHOD(Collection, lastIndexOf)
{
}
PHP_METHOD(Collection, map)
{

View File

@ -52,7 +52,6 @@ PHP_METHOD(Collection, isEmpty);
PHP_METHOD(Collection, isNotEmpty);
PHP_METHOD(Collection, keys);
PHP_METHOD(Collection, last);
PHP_METHOD(Collection, lastIndexOf);
PHP_METHOD(Collection, map);
PHP_METHOD(Collection, mapKeys);
PHP_METHOD(Collection, mapKeysTo);

View File

@ -331,7 +331,7 @@ class Collection implements ArrayAccess, Countable
* Returns key of the first element matching the given predicate, or null if the collection
* does not contain such element.
*
* @param callable $predicate ($value) -> bool
* @param callable $predicate[optional] ($value) -> bool
* @return int|string|null
*/
function indexOfFirst($predicate) {}
@ -340,7 +340,7 @@ class Collection implements ArrayAccess, Countable
* Returns key of the last element matching the given predicate, or null if the collection
* does not contain such element.
*
* @param callable $predicate ($value) -> bool
* @param callable $predicate[optional] ($value) -> bool
* @return int|string|null
*/
function indexOfLast($predicate) {}
@ -389,14 +389,6 @@ class Collection implements ArrayAccess, Countable
*/
function last($predicate) {}
/**
* Returns last key of element, or null if the collection does not contain element.
*
* @param mixed $element
* @return int|string|null
*/
function lastIndexOf($element) {}
/**
* Returns a collection containing the results of applying the given transform function
* to each element in the original collection.

10
tests/022-flatten.php Normal file
View File

@ -0,0 +1,10 @@
--TEST--
Test Collection::flatten().
--FILE--
<?php
$array = [['a', 'foo' => 'b'], ['c', 'd', ['e']], 'bar' => 'f'];
$collection = Collection::init($array)->flatten();
if ($collection->toArray() != ['a', 'foo' => 'b', 'c', 'd', ['e'], 'bar' => 'f'])
echo 'Collection::flatten() failed.', PHP_EOL;
?>
--EXPECT--