Add remove(), removeAll() and retainAll(). Fix readme.

This commit is contained in:
CismonX 2018-05-05 18:29:14 +08:00
parent bdaa0b7913
commit a57c1ba965
5 changed files with 102 additions and 13 deletions

View File

@ -20,7 +20,7 @@ See [stubs](stubs/) directory for signature of all classes and methods of this e
The `Collection` class implements `ArrayAccess` and `Countable` interface internally, you can treat an instance of `Collection` as an `ArrayObject`. The `Collection` class implements `ArrayAccess` and `Countable` interface internally, you can treat an instance of `Collection` as an `ArrayObject`.
* The `isset()`, `unset()` keywords can be used on elements of `Collection`. * The `isset()`, `unset()` keywords can be used on elements of `Collection`.
* Elements can be accessed via property (string keys only) and bracket expression. * Elements can be accessed via property and bracket expression.
* `empty()`, `count()` can be used on instance of `Collection`. * `empty()`, `count()` can be used on instance of `Collection`.
* Elements can be traversed via `foreach()` keyword. * Elements can be traversed via `foreach()` keyword.
@ -48,7 +48,7 @@ $names = Collection::init($employees)
->sortedByDescending(function ($value) { ->sortedByDescending(function ($value) {
return $value['age']; return $value['age'];
}) })
->map(function ($value) { ->mapValues(function ($value) {
return $value['name']; return $value['name'];
}) })
->toArray(); ->toArray();

View File

@ -5,6 +5,7 @@
// //
#include <php.h> #include <php.h>
#include <stdint.h>
#include "php_collections.h" #include "php_collections.h"
#include "php_collections_me.h" #include "php_collections_me.h"
@ -1142,17 +1143,77 @@ PHP_METHOD(Collection, reduceRight)
PHP_METHOD(Collection, remove) PHP_METHOD(Collection, remove)
{ {
zval* key;
zval* value = NULL;
ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_ZVAL(key)
Z_PARAM_OPTIONAL
Z_PARAM_ZVAL(value)
ZEND_PARSE_PARAMETERS_END();
zend_array* current = COLLECTION_FETCH_CURRENT();
zval* found;
if (Z_TYPE_P(key) == IS_LONG) {
if (value == NULL)
RETURN_BOOL(zend_hash_index_del(current, Z_LVAL_P(key)) == SUCCESS);
found = zend_hash_index_find(current, Z_LVAL_P(key));
if (found == NULL || fast_equal_check_function(found, value) == 0)
RETURN_FALSE;
RETURN_BOOL(zend_hash_index_del(current, Z_LVAL_P(key)) == SUCCESS);
}
if (Z_TYPE_P(key) == IS_STRING) {
if (value == NULL)
RETURN_BOOL(zend_hash_del(current, Z_STR_P(key)) == SUCCESS);
found = zend_hash_find(current, Z_STR_P(key));
if (found == NULL || fast_equal_check_function(found, value) == 0)
RETURN_FALSE;
RETURN_BOOL(zend_hash_del(current, Z_STR_P(key)) == SUCCESS);
}
ERR_BAD_KEY_TYPE();
RETVAL_FALSE;
} }
PHP_METHOD(Collection, removeAll) PHP_METHOD(Collection, removeAll)
{ {
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
zend_array* current = COLLECTION_FETCH_CURRENT();
SEPARATE_CURRENT_COLLECTION(current);
if (EX_NUM_ARGS() == 0) {
zend_hash_clean(current);
return;
}
INIT_FCI(2);
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
CALLBACK_KEYVAL_INVOKE(params, bucket);
if (zend_is_true(&retval))
zend_hash_del_bucket(current, bucket);
ZEND_HASH_FOREACH_END();
} }
PHP_METHOD(Collection, retainAll) PHP_METHOD(Collection, retainAll)
{ {
zend_fcall_info fci;
zend_fcall_info_cache fcc;
ZEND_PARSE_PARAMETERS_START(0, 1)
Z_PARAM_OPTIONAL
Z_PARAM_FUNC(fci, fcc)
ZEND_PARSE_PARAMETERS_END();
zend_array* current = COLLECTION_FETCH_CURRENT();
SEPARATE_CURRENT_COLLECTION(current);
if (EX_NUM_ARGS() == 0) {
zend_hash_clean(current);
return;
}
INIT_FCI(2);
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
CALLBACK_KEYVAL_INVOKE(params, bucket);
if (!zend_is_true(&retval))
zend_hash_del_bucket(current, bucket);
ZEND_HASH_FOREACH_END();
} }
PHP_METHOD(Collection, reverse) PHP_METHOD(Collection, reverse)
@ -1179,12 +1240,13 @@ PHP_METHOD(Collection, set)
Z_PARAM_ZVAL(value) Z_PARAM_ZVAL(value)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
zend_array* current = COLLECTION_FETCH_CURRENT(); zend_array* current = COLLECTION_FETCH_CURRENT();
SEPARATE_CURRENT_COLLECTION(current); if (Z_TYPE_P(key) == IS_STRING) {
if (Z_TYPE_P(key) == IS_STRING) SEPARATE_CURRENT_COLLECTION(current);
zend_hash_update(current, Z_STR_P(key), value); zend_hash_update(current, Z_STR_P(key), value);
else if (Z_TYPE_P(key) == IS_LONG) } else if (Z_TYPE_P(key) == IS_LONG) {
SEPARATE_CURRENT_COLLECTION(current);
zend_hash_index_update(current, Z_LVAL_P(key), value); zend_hash_index_update(current, Z_LVAL_P(key), value);
else } else
ERR_BAD_KEY_TYPE(); ERR_BAD_KEY_TYPE();
} }

View File

@ -680,14 +680,16 @@ class Collection implements ArrayAccess, Countable
* *
* @param int|string $key * @param int|string $key
* @param mixed $value[optional] * @param mixed $value[optional]
* @return bool
*/ */
function remove($key, $value) {} function remove($key, $value) {}
/** /**
* Removes all elements from this collection that match the given predicate. * Removes all elements from this collection that match the given predicate. If predicate is not
* provided, all elements will be removed.
* *
* @param callable $predicate ($value, $key) -> bool * @param callable $predicate[optional] ($value, $key) -> bool
* @return bool * @return void
*/ */
function removeAll($predicate) {} function removeAll($predicate) {}
@ -695,7 +697,7 @@ class Collection implements ArrayAccess, Countable
* Retains only elements of this collection that match the given predicate. * Retains only elements of this collection that match the given predicate.
* *
* @param callable $predicate ($value, $key) -> bool * @param callable $predicate ($value, $key) -> bool
* @return bool * @return void
*/ */
function retainAll($predicate) {} function retainAll($predicate) {}

View File

@ -13,5 +13,9 @@ if ($collection->toArray() != $array)
if ($collection->get('a') != $array['a'] || if ($collection->get('a') != $array['a'] ||
$collection->get('f', function ($key) { return $key; }) != 'f') $collection->get('f', function ($key) { return $key; }) != 'f')
echo 'Collection::get() failed.', PHP_EOL; echo 'Collection::get() failed.', PHP_EOL;
if (!$collection->remove('a') || !is_null($collection->get('a')))
echo 'Collection::remove() failed.', PHP_EOL;
if ($collection->remove('c', 'e') || $collection->get('c') != 'd')
echo 'Collection::remove() failed.', PHP_EOL;
?> ?>
--EXPECT-- --EXPECT--

View File

@ -0,0 +1,21 @@
--TEST--
Test Collection::removeAll() and Collection::retainAll().
--FILE--
<?php
$array = ['a' => 4, 'b' => 1, 'c' => 9, 'd' => -2, 'e' => 0];
$pred_is_odd = function ($value) {
return $value % 2;
};
$collection = Collection::init($array);
$collection->removeAll($pred_is_odd);
if ($collection->toArray() != ['a' => 4, 'd' => -2, 'e' => 0])
echo 'Collection::removeAll() failed.', PHP_EOL;
$collection->removeAll();
if ($collection->toArray() != [])
echo 'Collection::removeAll() failed.', PHP_EOL;
$collection = Collection::init($array);
$collection->retainAll($pred_is_odd);
if ($collection->toArray() != ['b' => 1, 'c' => 9])
echo 'Collection::retainAll() failed.', PHP_EOL;
?>
--EXPECT--