summaryrefslogtreecommitdiff
path: root/ext/standard/array.c
diff options
context:
space:
mode:
authorAndrei Zmievski <andrei@php.net>2001-10-27 05:11:15 +0000
committerAndrei Zmievski <andrei@php.net>2001-10-27 05:11:15 +0000
commit2890b57e469fa7940eb12245cd2c7bab2f52077a (patch)
treef3d4e7eea9b984328c56006ad3c5ce6d44dfc5e5 /ext/standard/array.c
parentdc107bf495e3ff3fb4e2b0e6dfe306d238d303cc (diff)
downloadphp-git-2890b57e469fa7940eb12245cd2c7bab2f52077a.tar.gz
@- Added array_chunk() function that splits an array into chunks of specified
@ size. (Andrei)
Diffstat (limited to 'ext/standard/array.c')
-rw-r--r--ext/standard/array.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 2807129fa0..4e931c76e7 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -3276,6 +3276,77 @@ PHP_FUNCTION(key_exists)
}
/* }}} */
+
+/* {{{ proto array array_chunk(array input, int size [, bool preserve_keys])
+ Split array into chunks */
+PHP_FUNCTION(array_chunk)
+{
+ int argc = ZEND_NUM_ARGS(), key_type;
+ long size, current = 0;
+ char *str_key;
+ uint str_key_len;
+ ulong num_key;
+ zend_bool preserve_keys = 0;
+ zval *input = NULL;
+ zval *chunk = NULL;
+ zval **entry;
+ HashPosition pos;
+
+ if (zend_parse_parameters(argc TSRMLS_CC, "al|b", &input, &size,
+ &preserve_keys) == FAILURE)
+ return;
+
+ /* Do bounds checking for size parameter. */
+ if (size < 1) {
+ php_error(E_WARNING, "%s() expects the size parameter to be > 0",
+ get_active_function_name(TSRMLS_C));
+ return;
+ }
+
+ array_init(return_value);
+
+ zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
+ while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void**)&entry, &pos) == SUCCESS) {
+ /* If new chunk, create and initialize it. */
+ if (!chunk) {
+ MAKE_STD_ZVAL(chunk);
+ array_init(chunk);
+ }
+
+ /* Add entry to the chunk, preserving keys if necessary. */
+ zval_add_ref(entry);
+
+ if (preserve_keys) {
+ key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &str_key,
+ &str_key_len, &num_key, 0, &pos);
+ if (key_type == HASH_KEY_IS_STRING) {
+ add_assoc_zval_ex(chunk, str_key, str_key_len, *entry);
+ } else {
+ add_index_zval(chunk, num_key, *entry);
+ }
+ } else {
+ add_next_index_zval(chunk, *entry);
+ }
+
+ /*
+ * If reached the chunk size, add it to the result array, and reset the
+ * pointer.
+ */
+ if (!(++current % size)) {
+ add_next_index_zval(return_value, chunk);
+ chunk = NULL;
+ }
+
+ zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
+ }
+
+ /* Add the final chunk if there is one. */
+ if (chunk) {
+ add_next_index_zval(return_value, chunk);
+ }
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4