Array slice function that works with associative arrays (keys):
function array_slice_assoc($array,$keys) {
return array_intersect_key($array,array_flip($keys));
}
(PHP 4, PHP 5, PHP 7)
array_slice — Extract a slice of the array
$array
, int $offset
[, int $length
= NULL
[, bool $preserve_keys
= FALSE
]] ) : array
array_slice() returns the sequence of elements
from the array array
as specified by the
offset
and length
parameters.
array
The input array.
offset
If offset
is non-negative, the sequence will
start at that offset in the array
.
If offset
is negative, the sequence will
start that far from the end of the array
.
Note:
The
offset
parameter denotes the position in the array, not the key.
length
If length
is given and is positive,
then the sequence will have up to that many elements in it.
If the array is shorter than the length
,
then only the available array elements will be present.
If length
is given and is negative then the
sequence will stop that many elements from the end of the array.
If it is omitted, then the sequence will have everything
from offset
up until the end of the
array
.
preserve_keys
Note:
array_slice() will reorder and reset the integer array indices by default. This behaviour can be changed by setting
preserve_keys
toTRUE
. String keys are always preserved, regardless of this parameter.
Returns the slice. If the offset is larger than the size of the array, an empty array is returned.
Version | Description |
---|---|
5.2.4 |
The default value of the length parameter was
changed to NULL . A NULL length now tells
the function to use the length of array .
Prior to this version, a NULL length was
taken to mean a zero length (nothing will be returned).
|
5.0.2 |
The optional preserve_keys parameter was added.
|
Example #1 array_slice() examples
<?php
$input = array("a", "b", "c", "d", "e");
$output = array_slice($input, 2); // returns "c", "d", and "e"
$output = array_slice($input, -2, 1); // returns "d"
$output = array_slice($input, 0, 3); // returns "a", "b", and "c"
// note the differences in the array keys
print_r(array_slice($input, 2, -1));
print_r(array_slice($input, 2, -1, true));
?>
The above example will output:
Array ( [0] => c [1] => d ) Array ( [2] => c [3] => d )
Example #2 array_slice() and one-based array
<?php
$input = array(1 => "a", "b", "c", "d", "e");
print_r(array_slice($input, 1, 2));
?>
The above example will output:
Array ( [0] => b [1] => c )
Example #3 array_slice() and array with mixed keys
<?php
$ar = array('a'=>'apple', 'b'=>'banana', '42'=>'pear', 'd'=>'orange');
print_r(array_slice($ar, 0, 3));
print_r(array_slice($ar, 0, 3, true));
?>
The above example will output:
Array ( [a] => apple [b] => banana [0] => pear ) Array ( [a] => apple [b] => banana [42] => pear )
Array slice function that works with associative arrays (keys):
function array_slice_assoc($array,$keys) {
return array_intersect_key($array,array_flip($keys));
}
array_slice can be used to remove elements from an array but it's pretty simple to use a custom function.
One day array_remove() might become part of PHP and will likely be a reserved function name, hence the unobvious choice for this function's names.
<?
function arem($array,$value){
$holding=array();
foreach($array as $k => $v){
if($value!=$v){
$holding[$k]=$v;
}
}
return $holding;
}
function akrem($array,$key){
$holding=array();
foreach($array as $k => $v){
if($key!=$k){
$holding[$k]=$v;
}
}
return $holding;
}
$lunch = array('sandwich' => 'cheese', 'cookie'=>'oatmeal','drink' => 'tea','fruit' => 'apple');
echo '<pre>';
print_r($lunch);
$lunch=arem($lunch,'apple');
print_r($lunch);
$lunch=akrem($lunch,'sandwich');
print_r($lunch);
echo '</pre>';
?>
(remove 9's in email)
<?php
// CHOP $num ELEMENTS OFF THE FRONT OF AN ARRAY
// RETURN THE CHOP, SHORTENING THE SUBJECT ARRAY
function array_chop(&$arr, $num)
{
$ret = array_slice($arr, 0, $num);
$arr = array_slice($arr, $num);
return $ret;
}
Using the varname function referenced from the array_search page, submitted by dcez at land dot ru. I created a multi-dimensional array splice function. It's usage is like so:
$array['admin'] = array('blah1', 'blah2');
$array['voice'] = array('blah3', 'blah4');
array_cut('blah4', $array);
...Would strip blah4 from the array, no matter where the position of it was in the array ^^ Returning this...
Array ( [admin] => Array ( [0] => blah1 [1] => blah2 ) [voice] => Array ( [0] => blah3 ) )
Here is the code...
<?php
function varname ($var)
{
// varname function by dcez at land dot ru
return (isset($var)) ? array_search($var, $GLOBALS) : false;
}
function array_cut($needle, $haystack)
{
foreach ($haystack as $k => $v)
{
for ($i=0; $i<count($v); $i++)
if ($v[$i] === $needle)
{
return array_splice($GLOBALS[varname($haystack)][$k], $i, 1);
break; break;
}
}
?>
Check out dreamevilconcept's forum for more innovative creations!
remember that array_slice returns an array with the current element. you must use array_slice($array, $index+1) if you want to get the next elements.
If you want an associative version of this you can do the following:
function array_slice_assoc($array,$keys) {
return array_intersect_key($array,array_flip($keys));
}
However, if you want an inverse associative version of this, just use array_diff_key instead of array_intersect_key.
function array_slice_assoc_inverse($array,$keys) {
return array_diff_key($array,array_flip($keys));
}
Example:
$arr = [
'name' => 'Nathan',
'age' => 20,
'height' => 6
];
array_slice_assoc($arr, ['name','age']);
will return
Array (
'name' = 'Nathan',
'age' = 20
)
Where as
array_slice_assoc_inverse($arr, ['name']);
will return
Array (
'age' = 20,
'height' = 6
)
To save the sort order of a numeric index in the array. Version php =>5.5.26
/*
Example
*/
$arr = array( "1" =>2, "2" =>3 , "3" =>5 );
print_r(array_slice($arr,1,null,true));
/*
Result
Array
(
[2] => 3
[3] => 5
)
*/
<?php
/**
* @desc
* Combines two arrays by inserting one into the other at a given position then
* returns the result.
*
* @since 2007/10/04
* @version v0.7 2007/10/04 18:47:52
* @author AexChecker <AexChecker@yahoo.com>
* @param array $source
* @param array $destination
* @param int [optional] $offset
* @param int [optional] $length
* @return array
*/
function array_insert($source, $destination, $offset = NULL, $length = NULL) {
if (!is_array($source) || empty($source)) {
if (is_array($destination) && !empty($destination)) {
return $destination;
}
return array();
}
if (is_null($offset)) {
return array_merge($destination, $source);
}
$offset = var2int($offset);
if (is_null($length)) {
if ($offset === 0) {
return array_merge($source, array_slice($destination, 1));
}
if ($offset === -1) {
return array_merge(array_slice($destination, 0, -1), $source);
}
return array_merge(
array_slice($destination, 0, $offset),
$source,
array_slice($destination, ++$offset)
);
}
if ($offset === 0) {
return array_merge($source, array_slice($destination, $length));
}
$destination_count = count($destination);
$length = var2int($length);
if ($offset > 0) {
if ($destination_count - $offset < 1) {
return array_merge($destination, $source);
}
} else{
if (($t = $destination_count + $offset) < 1) {
return array_merge($source, $destination);
}
$offset = $t;
}
if ($length > 0) {
$length+= $offset;
} elseif ($length < 0 && !($length * -1 < $destination_count)) {
return $source;
} else {
$length = $offset;
}
return array_merge(
array_slice($destination, 0, $offset),
$source,
array_slice($destination, $length)
);
}
?>
I was trying to find a good way to find the previous several and next several results from an array created in a MySQL query. I found that most MySQL solutions to this problem were complex. Here is a simple function that returns the previous and next rows from the array.
<?php
/*
** function array_surround by Jamon Holmgren of ClearSight Design
** Version 1.0 - 4/10/2009
** Please direct comments and questions to my first name at symbol clearsightdesign.com
**
** Returns an array with only the $before and $after number of results
** This is set to work best with MySQL data results
** Use this to find the rows immediately before and after a particular row, as many as you want
**
** Example usage:
** $mysql_ar is an array of results from a MySQL query and the current id is $cur_id
** We want to get the row before this one and five rows afterward
**
** $near_rows = array_surround($mysql_ar, "id", $cur_id, 1, 5)
**
** Previous row is now $near_rows[-1]
** Current row is now $near_rows[0]
** Next row is $near_rows[1] ... etc
** If there is no previous row, $near_rows[-1] will not be set...test for it with is_array($near_rows[-1])
**
*/
function array_surround($src_array, $field, $value, $before = 1, $after = 1) {
if(is_array($src_array)) {
// reset all the keys to 0 through whatever in case they aren't sequential
$new_array = array_values($src_array);
// now loop through and find the key in array that matches the criteria in $field and $value
foreach($new_array as $k => $s) {
if($s[$field] == $value) {
// Found the one we wanted
$ck = $k; // put the key in the $ck (current key)
break;
}
}
if(isset($ck)) { // Found it!
$result_start = $ck - $before; // Set the start key
$result_length = $before + 1 + $after; // Set the number of keys to return
if($result_start < 0) { // Oops, start key is before first result
$result_length = $result_length + $result_start; // Reduce the number of keys to return
$result_start = 0; // Set the start key to the first result
}
$result_temp = array_slice($new_array, $result_start, $result_length); // Slice out the results we want
// Now we have an array, but we want array[-$before] to array[$after] not 0 to whatever.
foreach($result_temp as $rk => $rt) { // set all the keys to -$before to +$after
$result[$result_start - $ck + $rk] = $rt;
}
return $result;
} else { // didn't find it!
return false;
}
} else { // They didn't send an array
return false;
}
}
?>
I hope you find this useful! I welcome constructive criticism or comments or of course praise ;) -- just e-mail me.
- Jamon Holmgren
If you want to remove a specified entry from an array i made this mwethod...
<?php
$array = array("Entry1","entry2","entry3");
$int = 3; //Number of entries in the array
$int2 = 0; //Starter array spot... it will begine its search at 0.
$del_num = 1; //Represents the second entry in the array... which is the one we will happen to remove this time... i.e. 0 = first entry, 1 = second entry, 2 = third...........
$newarray = array(); //Empty array that will be the new array minus the specified entry...
print_r($array) . "<br>"; //print original array contents
print_r($newarray). "<br>"; //print the new empty array
do
{
$user = $array[$int2];
$key = array_search($user, $array);
if ($key == $del_num)
{
}
else
{
$newarray[] = $array[$int2];
}
$int2 = $int2 + 1;
} while ($int2 < $int);
print_r($newarray). "<br>"; //print the new array
?>
based on worldclimb's arem(), here is a recursive array value removal tool that can work with multidimensional arrays.
function remove_from_array($array,$value){
$clear = true;
$holding=array();
foreach($array as $k => $v){
if (is_array($v)) {
$holding [$k] = remove_from_array ($v, $value);
}
elseif ($value == $v) {
$clear = false;
}
elseif($value != $v){
$holding[$k]=$v; // removes an item by combing through the array in order and saving the good stuff
}
}
if ($clear) return $holding; // only pass back the holding array if we didn't find the value
}
For those with PHP < 5.0.2, and have a number as your array key, to avoid having the key reset with array_slice, add a blank character to the beginning or end of the key.
<?
$array[" ".$key] = $value;
?>
Note that if $offset+$length>count($array) then resulting array will NOT be filled with empty elements at his end, so it is not sure that it will have exactly $length elements. Example:
<?php
$a=Array(7,32,11,24,65); // count($a) is 5
$b=array_slice($a,2,4); // 2+4=6, and 6>count($a)
print_r($b);
?>
will return a 3-elements array:
Array
(
[0] => 11
[1] => 24
[2] => 65
)
<?php
// Combines two arrays by inserting one into the other at a given position then returns the result
function array_insert($src, $dest, $pos) {
if (!is_array($src) || !is_array($dest) || $pos <= 0) return FALSE;
return array_merge(array_slice($dest, 0, $pos), $src, array_slice($dest, $pos));
}
?>
<?php
/**
* Reorders an array by keys according to a list of values.
* @param array $array the array to reorder. Passed by reference
* @param array $list the list to reorder by
* @param boolean $keepRest if set to FALSE, anything not in the $list array will be removed.
* @param boolean $prepend if set to TRUE, will prepend the remaining values instead of appending them
* @author xananax AT yelostudio DOT com
*/
function array_reorder(array &$array,array $list,$keepRest=TRUE,$prepend=FALSE,$preserveKeys=TRUE){
$temp = array();
foreach($list as $i){
if(isset($array[$i])){
$tempValue = array_slice(
$array,
array_search($i,array_keys($array)),
1,
$preserveKeys
);
$temp[$i] = array_shift($tempValue);
unset($array[$i]);
}
}
$array = $keepRest ?
($prepend?
$array+$temp
:$temp+$array
)
: $temp;
}
/** exemple ** /
$a = array(
'a' => 'a',
'b' => 'b',
'c' => 'c',
'd' => 'd',
'e' => 'e'
);
$order = array('c','b','a');
array_reorder($a,$order,TRUE);
echo '<pre>';
print_r($a);
echo '</pre>';
/** exemple end **/
?>
just a little tip.
to preserve keys without providing length: use NULL
array_slice($array, $my_offset, NULL, true);
Note that offset is not the same thing as key. Offset always starts at 0, while keys might be any number.
So this:
<?php print_r(array_slice(array(0 => 0, 5 => 5, 13 => 13),1)); ?>
will result in this:
Array
(
[0] => 5
[1] => 13
)
( If $offset is negative and abs($length)>count($length) ) or ( $offset>count($array) ) etc, array_slice returns empty array. For example:
<?php
$array = array(
'a'=>'1',
'b'=>'2',
'c'=>'3',
'd'=>'4',
'e'=>'5',
'f'=>'6',
'g'=>'7',
'h'=>'8'
);
print_r( array_slice($test, 2, -10) );
print_r( array_slice($test, 10, 1) );
print_r( array_slice($test, 10, 15) );
//prints
//Array()
//Array()
//Array()
?>
Sometimes you need to pick certain non-integer and/or non-sequential keys out of an array. Consider using the array_pick() implementation below to pull specific keys, in a specific order, out of a source array:
<?php
$a = array ('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4);
$b = array_pick($a, array ('d', 'b'));
// now:
// $a = array ('a' => 1, 'c' => '3');
// $b = array ('d' => 4, 'b' => '2');
function &array_pick(&$array, $keys)
{
if (! is_array($array)) {
trigger_error('First parameter must be an array', E_USER_ERROR);
return false;
}
if (! (is_array($keys) || is_scalar($keys))) {
trigger_error('Second parameter must be an array of keys or a scalar key', E_USER_ERROR);
return false;
}
if (is_array($keys)) {
// nothing to do
} else if (is_scalar($keys)) {
$keys = array ($keys);
}
$resultArray = array ();
foreach ($keys as $key) {
if (is_scalar($key)) {
if (array_key_exists($key, $array)) {
$resultArray[$key] = $array[$key];
unset($array[$key]);
}
} else {
trigger_error('Supplied key is not scalar', E_USER_ERROR);
return false;
}
}
return $resultArray;
}
?>
Thank to taylorbarstow here the function with the unset feature.
<?php
function array_slice_assoc(&$array,$keys,$unset = true) {
$return = array_intersect_key($array, array_flip($keys));
if ($unset) {
foreach ($keys as $value) {
unset($array[$value]);
}
}
return $return;
}
?>
/**
* Remove a value from a array
* @param string $val
* @param array $arr
* @return array $array_remval
*/
function array_remval($val, &$arr)
{
$array_remval = $arr;
for($x=0;$x<count($array_remval);$x++)
{
$i=array_search($val,$array_remval);
if (is_numeric($i)) {
$array_temp = array_slice($array_remval, 0, $i );
$array_temp2 = array_slice($array_remval, $i+1, count($array_remval)-1 );
$array_remval = array_merge($array_temp, $array_temp2);
}
}
return $array_remval;
}
$stack=Array('apple','banana','pear','apple', 'cherry', 'apple');
array_remval("apple", $stack);
//output: Array('banana','pear', 'cherry')
If you specify the fourth argument (to not reassign the keys), then there appears to be no way to get the function to return all values to the end of the array. Assigning -0 or NULL or just putting two commas in a row won't return any results.
I noticed that some other people made supportive functions for maintaining numeric keys for PHP versions less than 5.0.2. So here is my version of it.
<?php
//Slice an array but keep numeric keys
function narray_slice($array, $offset, $length) {
//Check if this version already supports it
if (str_replace('.', '', PHP_VERSION) >= 502)
return array_slice($array, $offset, $length, true);
foreach ($array as $key => $value) {
if ($a >= $offset && $a - $offset <= $length)
$output_array[$key] = $value;
$a++;
}
return $output_array;
}
?>
In reply to jenny at jennys dot info:
Here is a much easier way to find the $offset of a $key in an $array:
$offset = array_search($key, array_keys($array));
My shot at Dams's array_slice_key() implementation:
function array_slice_key($array, $offset, $len=-1){
if (!is_array($array))
return FALSE;
$length = $len >= 0? $len: count($array);
$keys = array_slice(array_keys($array), $offset, $length);
foreach($keys as $key) {
$return[$key] = $array[$key];
}
return $return;
}
Here's a function which returns the array offset based on the array key. This is useful if you'd like to use array_slice to get all keys/values after key "foo".
<?
function array_offset($array, $offset_key) {
$offset = 0;
foreach($array as $key=>$val) {
if($key == $offset_key)
return $offset;
$offset++;
}
return -1;
}
$array = array('foo'=>'foo', 'bar'=>'bar', 'bash'=>'bash', 'quux'=>'quux');
print_r($array);
// Prints the following:
// Array
// (
// [foo] => foo
// [bar] => bar
// [bash] => bash
// [quux] => quux
// )
$offset = array_offset($array,'bar');
// $offset now contains '1'
$new = array_slice($array,$offset+1);
print_r($new);
// Prints the following:
// Array
// (
// [bash] => bash
// [quux] => quux
// )
?>
A flexible array_split function:
<?php
// split the given array into n number of pieces
function array_split($array, $pieces=2)
{
if ($pieces < 2)
return array($array);
$newCount = ceil(count($array)/$pieces);
$a = array_slice($array, 0, $newCount);
$b = array_split(array_slice($array, $newCount), $pieces-1);
return array_merge(array($a),$b);
}
// Examples:
$a = array(1,2,3,4,5,6,7,8,9,10);
array_split($a, 2); // array(array(1,2,3,4,5), array(6,7,8,9,10))
array_split($a, 3); // array(array(1,2,3,4), array(5,6,7), array(8,9,10))
array_split($a, 4); // array(array(1,2,3), array(4,5,6), array(7,8), array(9,10))
?>
An implementation of array_slice that do not resets the cursor.
<?php
function get_from_array($arr, $start, $length)
{
$sliced = array();
foreach ($arr as $k => $v)
{
if ($start <= $k && $k <= $start + $length - 1)
{
$sliced[] = $v;
if (count($sliced) == $length) break;
}
}
return $sliced;
}
?>
Cheers,
Joel A. Villarreal Bertoldi
The version check on "ps at b1g dot de" function fails on my copy of PHP. My Version of PHP is "4.3.10-18", and it ends up checking 4310 <=> 502.
Since we are looking for a version over 4.1.0, we cas use version_compare.
<?php
// PHP >= 5.0.2 is able to do this itself
if(function_exists('version_compare') and version_compare(PHP_VERSION, '5.0.2') >= 0) {
return array_slice($array, $offset, $length, true);
}
?>
Hmm ... i wrote an usefull function whitch is such like strpos but it works on arrays ;]
<?php
/*
* Find position of first occurrence of a array
*
* @param array $haystack
* @param array $needle
* @return int
* @author FanFataL
*/
function array_pos($haystack, $needle) {
$size = count($needle);
$sizeh = count($haystack);
if($size > $sizeh) return false;
$scale = $sizeh - $size + 1;
for($i = 0; $i < $scale; $i++)
if($needle === array_slice($haystack, $i, $size))
return $i;
return false;
}
// Sample:
$a = array('aa','bb','cc','dd','ee');
$b = array('cc','dd');
$pos = array_pos($a, $b);
?>
Greatings ;-)
...
By combining this with str_split() and implode(),slices can also be excerpted from strings with the following simple function:
<?php
function str_slice($string,$offset,$length=999,$preserve_keys=False){
if( $length == 999 ){ $length = strlen($string)-$offset };
$slice_arr = array_slice(str_split($string),$offset,$length,$preserve_keys);
return implode($slice_arr);
};
?>
Perhaps there's a better way to preset $length.
It should be noted that this function does NOT modify the original array. So if you need to array_pop() or array_shift() without modifying the original array, you can use array_slice().
<?php
$input = array('a', 'b', 'c');
$output = array_slice($input, 1);
print_r($output);
print_r($input);
/*
Array
(
[0] => b
[1] => c
)
Array
(
[0] => a
[1] => b
[2] => c
)
*/
?>
Use unset() to delete a associative array.
Ex:
<?php
$item['chaise'] = array ('qty' => 1,
'desc' => 'Chaise bercante 10"',
'avail' => 10);
$item['divan'] = array ('qty' => 1,
'desc' => 'Divan brun laitte"',
'avail' => 10);
if (isset($item['chaise'])) {
++$item['chaise']['qty'];
}
unset($item['divan']);
foreach ($item as $s) {
echo "<br />Commande " . $s['qty'] . " " . $s['desc'];
}
?>