Skip to content

Commit d1335d1

Browse files
committed
add function list_filter
1 parent 787f26c commit d1335d1

File tree

4 files changed

+109
-1
lines changed

4 files changed

+109
-1
lines changed

ext/standard/array.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6582,6 +6582,83 @@ PHP_FUNCTION(array_filter)
65826582
}
65836583
/* }}} */
65846584

6585+
/* {{{ Filters elements from the array via the callback. */
6586+
PHP_FUNCTION(list_filter)
6587+
{
6588+
zval *array;
6589+
zval *operand;
6590+
zval *key;
6591+
zval args[2];
6592+
zval retval;
6593+
bool have_callback = 0;
6594+
zend_long use_type = 0;
6595+
zend_string *string_key;
6596+
zend_fcall_info fci = empty_fcall_info;
6597+
zend_fcall_info_cache fci_cache = empty_fcall_info_cache;
6598+
zend_ulong num_key;
6599+
6600+
ZEND_PARSE_PARAMETERS_START(1, 3)
6601+
Z_PARAM_ARRAY(array)
6602+
Z_PARAM_OPTIONAL
6603+
Z_PARAM_FUNC_OR_NULL(fci, fci_cache)
6604+
Z_PARAM_LONG(use_type)
6605+
ZEND_PARSE_PARAMETERS_END();
6606+
6607+
if (zend_hash_num_elements(Z_ARRVAL_P(array)) == 0) {
6608+
RETVAL_EMPTY_ARRAY();
6609+
return;
6610+
}
6611+
array_init(return_value);
6612+
6613+
if (ZEND_FCI_INITIALIZED(fci)) {
6614+
have_callback = 1;
6615+
fci.retval = &retval;
6616+
if (use_type == ARRAY_FILTER_USE_BOTH) {
6617+
fci.param_count = 2;
6618+
key = &args[1];
6619+
} else {
6620+
fci.param_count = 1;
6621+
key = &args[0];
6622+
}
6623+
}
6624+
6625+
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, operand) {
6626+
if (have_callback) {
6627+
if (use_type) {
6628+
/* Set up the key */
6629+
if (!string_key) {
6630+
ZVAL_LONG(key, num_key);
6631+
} else {
6632+
ZVAL_STR(key, string_key);
6633+
}
6634+
}
6635+
if (use_type != ARRAY_FILTER_USE_KEY) {
6636+
ZVAL_COPY_VALUE(&args[0], operand);
6637+
}
6638+
fci.params = args;
6639+
6640+
zend_result result = zend_call_function(&fci, &fci_cache);
6641+
ZEND_ASSERT(result == SUCCESS);
6642+
6643+
if (UNEXPECTED(EG(exception))) {
6644+
RETURN_THROWS();
6645+
}
6646+
6647+
if (!php_is_true(&retval)) {
6648+
continue;
6649+
}
6650+
} else if (!zend_is_true(operand)) {
6651+
continue;
6652+
}
6653+
6654+
zval new_val;
6655+
ZVAL_COPY(&new_val, operand);
6656+
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val);
6657+
zval_add_ref(operand);
6658+
} ZEND_HASH_FOREACH_END();
6659+
}
6660+
/* }}} */
6661+
65856662
/* {{{ Internal function to find an array element for a user closure. */
65866663
enum php_array_find_result {
65876664
PHP_ARRAY_FIND_EXCEPTION = -1,

ext/standard/basic_functions.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1877,6 +1877,8 @@ function array_reduce(array $array, callable $callback, mixed $initial = null):
18771877

18781878
function array_filter(array $array, ?callable $callback = null, int $mode = 0): array {}
18791879

1880+
function list_filter(array $array, ?callable $callback = null, int $mode = 0): array {}
1881+
18801882
function array_find(array $array, callable $callback): mixed {}
18811883

18821884
function array_find_key(array $array, callable $callback): mixed {}

ext/standard/basic_functions_arginfo.h

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Test list_filter() function
3+
--FILE--
4+
<?php
5+
6+
$array1 = [1,0,2,3,4];
7+
$array2 = ['a' => 1, 'b' => 2, 'c' => 3];
8+
9+
var_dump(array_is_list($array1));
10+
var_dump(array_is_list(array_filter($array1)));
11+
var_dump(array_is_list(list_filter($array1)));
12+
13+
14+
var_dump(array_is_list($array2));
15+
var_dump(array_is_list(array_filter($array2)));
16+
var_dump(array_is_list(list_filter($array2)));
17+
18+
?>
19+
--EXPECT--
20+
bool(true)
21+
bool(false)
22+
bool(true)
23+
bool(false)
24+
bool(false)
25+
bool(true)

0 commit comments

Comments
 (0)