Built-in PHP function to reset the indexes of an array? - php

Example:
$arr = array(1 => 'Foo', 5 => 'Bar', 6 => 'Foobar');
/*... do some function so $arr now equals:
array(0 => 'Foo', 1 => 'Bar', 2 => 'Foobar');
*/

Use array_values($arr). That will return a regular array of all the values (indexed numerically).
PHP docs for array_values

array_values($arr);

To add to the other answers, array_values() will not preserve string keys. If your array has a mix of string keys and numeric keys (which is probably an indication of bad design, but may happen nonetheless), you can use a function like:
function reset_numeric_keys($array = array(), $recurse = false) {
$returnArray = array();
foreach($array as $key => $value) {
if($recurse && is_array($value)) {
$value = reset_numeric_keys($value, true);
}
if(gettype($key) == 'integer') {
$returnArray[] = $value;
} else {
$returnArray[$key] = $value;
}
}
return $returnArray;
}

Not that I know of, you might have already checked functions here
but I can imagine writing a simple function myself
resetarray($oldarray)
{
for(int $i=0;$i<$oldarray.count;$i++)
$newarray.push(i,$oldarray[i])
return $newarray;
}
I am little edgy on syntax but I guess u got the idea.

Related

php get array element and remove it from array at once

I have array:
$arr = array(
'a' => 1,
'b' => 2,
'c' => 3
);
Is there built-in php function which gets array value by key and then removes element from this array?
I know array_shift and array_pop functions, but I need to get element by custom key, not first/last element. Something like:
$arr; // 'a'=>1, 'b'=>2, 'c'=>3
$elem = array_shift_key($arr, 'b');
echo $elem; // 2
$arr; // 'a'=>1, 'c'=>3
Not sure about native way, but this should work:
function shiftByKey($key, &$array) {
if (!array_key_exists($key, $array)) {
return false;
}
$tmp = $array[$key];
unset($array[$key]);
return $tmp;
}
Edit: Updated it so that array is passed by reference. Else your array stays the same.
As far as I'm aware there's nothing that comes close to that. Can be written easily though:
function array_shift_key(array &$array, $key) {
$value = $array[$key];
unset($array[$key]);
return $value;
}
If you care, validate first whether the key exists in the array and do something according to your error handling philosophy if it doesn't. Otherwise you'll simply get a standard PHP notice for non-existing keys.
function array_shift_key(array &$input, $key) {
$value = null;
// Probably key presents with null value
if (isset($input[$key]) || array_key_exists($key, $input)) {
$value = $input[$key];
unset($input[$key]);
}
return $value;
}

How can I return the minimum key in an array?

Is there an equivalent min() for the keys in an array?
Given the array:
$arr = array(300 => 'foo', 200 => 'bar');
How can I return the minimum key (200)?
Here's one approach, but I have to imagine there's an easier way.
function minKey($arr) {
$minKey = key($arr);
foreach ($arr as $k => $v) {
if ($k < $minKey) $minKey = $k;
}
return $minKey;
}
$arr = array(300 => 'foo', 200 => 'bar');
echo minKey($arr); // 200
Try this:
echo min(array_keys($arr));
Try with
echo min(array_keys($arr));
min() is a php function that will return the lowest value of a set. array_keys() is a function that will return all keys of an array. Combine them to obtain what you want.
If you want to learn more about this two functions, please take a look to min() php guide and array_keys() php guide
use array_search() php function.
array_search(min($arr), $arr);
above code will print 200 when you echo it.
For echoing the value of lowest key use below code,
echo $arr[array_search(min($arr), $arr)];
Live Demo
This also would be helpful for others,
<?php
//$arr = array(300 => 'foo', 200 => 'bar');
$arr = array("0"=>array('price'=>100),"1"=>array('price'=>50));
//here price = column name
echo minOfKey($arr, 'price');
function minOfKey($array, $key) {
if (!is_array($array) || count($array) == 0) return false;
$min = $array[0][$key];
foreach($array as $a) {
if($a[$key] < $min) {
$min = $a[$key];
}
}
return $min;
}
?>
$arr = array(
300 => 'foo', 200 => 'bar'
);
$arr2=array_search($arr , min($arr ));
echo $arr2;

PHP Deep Extend Array

How can I do a deep extension of a multi dimensional associative array (for use with decoded JSON objects).
I need the php equivalent of jQuery's $.extend(true, array1, array2) with arrays instead of JSON and in PHP.
Here's an example of what I need (array_merge_recursive didn't seem to do the same thing)
$array1 = ('1'=> ('a'=>'array1a', 'b'=>'array1b'));
$array2 = ('1'=> ('a'=>'array2a', 'c'=>'array2b'));
$array3 = array_extend($array1, $array2);
//$array3 = ('1'=> ('a'=>'array2a', 'b'=>'array1b', 'c'=>'array2b'))
Notice how array2 overrides array1 if it has same value (like how extension of classes works)
If you have PHP 5.3.0+, you can use array_replace_recursive which does exactly what you need:
array_replace_recursive() replaces the values of array1 with the same
values from all the following arrays. If a key from the first array
exists in the second array, its value will be replaced by the value
from the second array. If the key exists in the second array, and not
the first, it will be created in the first array. If a key only exists
in the first array, it will be left as is. If several arrays are
passed for replacement, they will be processed in order, the later
array overwriting the previous values.
This might be what you're looking for:
function array_extend(&$result) {
if (!is_array($result)) {
$result = array();
}
$args = func_get_args();
for ($i = 1; $i < count($args); $i++) {
// we only work on array parameters:
if (!is_array($args[$i])) continue;
// extend current result:
foreach ($args[$i] as $k => $v) {
if (!isset($result[$k])) {
$result[$k] = $v;
}
else {
if (is_array($result[$k]) && is_array($v)) {
array_extend($result[$k], $v);
}
else {
$result[$k] = $v;
}
}
}
}
return $result;
}
Usage:
$arr1 = array('a' => 1, 'b' => 2, 'c' => 3);
$arr2 = array('b' => 'b', 'd' => 'd');
array_extend($arr1, $arr2);
print_r($arr1); // array('a' => 1, 'b' => 'b', 'c' => 3, 'd' => 'd')
// or, to create a new array and leave $arr1 unchanged use:
array_extend($arr3, $arr1, $arr2);
print_r($arr3); // array('a' => 1, 'b' => 'b', 'c' => 3, 'd' => 'd')
// or, use the return value:
print_r(array_extend($arr1, $arr2)); // but this will also modify $arr1
I use this in the same way I use angular.extend(dst, src) and jQuery.extend().
function extend($base = array(), $replacements = array()) {
$base = ! is_array($base) ? array() : $base;
$replacements = ! is_array($replacements) ? array() : $replacements;
return array_replace_recursive($base, $replacements);
}
Example:
si() is a utility sanitize function that grabs $_POST or $_GET and returns an array.
$s = extend(array(
'page' => 1,
'take' => 100,
'completed' => 1,
'incomplete' => 1,
), si());
Taken from array_merge docs:
function array_extend($a, $b) {
foreach($b as $k=>$v) {
if( is_array($v) ) {
if( !isset($a[$k]) ) {
$a[$k] = $v;
} else {
$a[$k] = array_extend($a[$k], $v);
}
} else {
$a[$k] = $v;
}
}
return $a;
}
You should use: https://github.com/appcia/webwork/blob/master/lib/Appcia/Webwork/Storage/Config.php#L64
/**
* Merge two arrays recursive
*
* Overwrite values with associative keys
* Append values with integer keys
*
* #param array $arr1 First array
* #param array $arr2 Second array
*
* #return array
*/
public static function merge(array $arr1, array $arr2)
{
if (empty($arr1)) {
return $arr2;
} else if (empty($arr2)) {
return $arr1;
}
foreach ($arr2 as $key => $value) {
if (is_int($key)) {
$arr1[] = $value;
} elseif (is_array($arr2[$key])) {
if (!isset($arr1[$key])) {
$arr1[$key] = array();
}
if (is_int($key)) {
$arr1[] = static::merge($arr1[$key], $value);
} else {
$arr1[$key] = static::merge($arr1[$key], $value);
}
} else {
$arr1[$key] = $value;
}
}
return $arr1;
}
With a little googling I found this:
/**
* jquery style extend, merges arrays (without errors if the passed values are not arrays)
*
* #return array $extended
**/
function extend() {
$args = func_get_args();
$extended = array();
if(is_array($args) && count($args)) {
foreach($args as $array) {
if(is_array($array)) {
$extended = array_merge($extended, $array);
}
}
}
return $extended;
}
extend($defaults, $new_options);
I guess here is the correct answer, because:
your answer have a bug with warning:
Warning: Cannot use a scalar value as an array in...
Because $a is not always an array and you use $a[$k].
array_merge_recursive does indeed merge arrays, but it converts values with duplicate keys to arrays rather than overwriting the value in the first array with the duplicate value in the second array, as array_merge does.
other aswers are not recursives or not simple.
So, here is my answer: your answer without bugs:
function array_extend(array $a, array $b) {
foreach($b as $k=>$v) {
if( is_array($v) ) {
if( !isset($a[$k]) ) {
$a[$k] = $v;
} else {
if( !is_array($a[$k]){
$a[$k]=array();
}
$a[$k] = array_extend($a[$k], $v);
}
} else {
$a[$k] = $v;
}
}
return $a;
}
And my answer with ternary operator:
function array_extend(array $a, array $b){
foreach($b as $k=>$v)
$a[$k] = is_array($v)&&isset($a[$k])?
array_extend(is_array($a[$k])?
$a[$k]:array(),$v):
$v;
return $a;
}
Edit: And a bonus one with as many arrays you want:
function array_extend(){
$args = func_get_args();
while($extended = array_shift($args))
if(is_array($extended))
break;
if(!is_array($extended))
return FALSE;
while($array = array_shift($args)){
if(is_array($array))
foreach($array as $k=>$v)
$extended[$k] = is_array($v)&&isset($extended[$k])?
array_extend(is_array($extended[$k])?
$extended[$k]:array(),$v):
$v;
}
return $extended;
}

Selecting an element in an Associative Array in a different way in PHP

Ok I have this kind of associative array in PHP
$arr = array(
"fruit_aac" => "apple",
"fruit_2de" => "banana",
"fruit_ade" => "grapes",
"other_add" => "sugar",
"other_nut" => "coconut",
);
now what I want is to select only the elements that starts with key fruit_. How can be this possible? can I use a regex? or any PHP array functions available? Is there any workaround? Please give some examples for your solutions
$fruits = array();
foreach ($arr as $key => $value) {
if (strpos($key, 'fruit_') === 0) {
$fruits[$key] = $value;
}
}
One solution is as follows:
foreach($arr as $key => $value){
if(strpos($key, "fruit_") === 0) {
...
...
}
}
The === ensures that the string was found at position 0, since strpos can also return FALSE if string was not found.
You try it:
function filter($var) {
return strpos($var, 'fruit_') !== false;
}
$arr = array(
"fruit_aac"=>"apple",
"fruit_2de"=>"banana",
"fruit_ade"=>"grapes",
"other_add"=>"sugar",
"other_nut"=>"coconut",
);
print_r(array_flip(array_filter(array_flip($arr), 'filter')));
If you want to try regular expression then you can try code given below...
$arr = array("fruit_aac"=>"apple",
"fruit_2de"=>"banana",
"fruit_ade"=>"grapes",
"other_add"=>"sugar",
"other_nut"=>"coconut",
);
$arr2 = array();
foreach($arr AS $index=>$array){
if(preg_match("/^fruit_.*/", $index)){
$arr2[$index] = $array;
}
}
print_r($arr2);
I hope it will be helpful for you.
thanks

Determine if a PHP array uses keys or indices [duplicate]

This question already has answers here:
How to check if PHP array is associative or sequential?
(60 answers)
Closed 9 years ago.
How do I find out if a PHP array was built like this:
array('First', 'Second', 'Third');
Or like this:
array('first' => 'First', 'second' => 'Second', 'third' => 'Third');
???
I have these simple functions in my handy bag o' PHP tools:
function is_flat_array($ar) {
if (!is_array($ar))
return false;
$keys = array_keys($ar);
return array_keys($keys) === $keys;
}
function is_hash($ar) {
if (!is_array($ar))
return false;
$keys = array_keys($ar);
return array_keys($keys) !== $keys;
}
I've never tested its performance on large arrays. I mostly use it on arrays with 10 or fewer keys so it's not usually an issue. I suspect it will have better performance than comparing $keys to the generated range 0..count($array).
print_r($array);
There is no difference between
array('First', 'Second', 'Third');
and
array(0 => 'First', 1 => 'Second', 2 => 'Third');
The former just has implicit keys rather than you specifying them
programmatically, you can't. I suppose the only way to check in a case like yours would be to do something like:
foreach ($myarray as $key => $value) {
if ( is_numeric($key) ) {
echo "the array appears to use numeric (probably a case of the first)";
}
}
but this wouldn't detect the case where the array was built as $array = array(0 => "first", 1 => "second", etc);
function is_assoc($array) {
return (is_array($array)
&& (0 !== count(array_diff_key($array, array_keys(array_keys($array))))
|| count($array)==0)); // empty array is also associative
}
here's another
function is_assoc($array) {
if ( is_array($array) && ! empty($array) ) {
for ( $i = count($array) - 1; $i; $i-- ) {
if ( ! array_key_exists($i, $array) ) { return true; }
}
return ! array_key_exists(0, $array);
}
return false;
}
Gleefully swiped from the is_array comments on the PHP documentation site.
That's a little tricky, especially that this form array('First', 'Second', 'Third'); implicitly lets PHP generate keys values.
I guess a valid workaround would go something like:
function array_indexed( $array )
{
$last_k = -1;
foreach( $array as $k => $v )
{
if( $k != $last_k + 1 )
{
return false;
}
$last_k++;
}
return true;
}
If you have php > 5.1 and are only looking for 0-based arrays, you can shrink the code to
$stringKeys = array_diff_key($a, array_values($a));
$isZeroBased = empty($stringKeys);
I Hope this will help you
Jerome WAGNER
function isAssoc($arr)
{
return $arr !== array_values($arr);
}

Categories