Call global dynamic variable from a function - php

Is there a way to call a dynamic variable within a function that was set up outside the function, such as making it a global variable.
$a = 'test'
$b = 'cat'
$c = 'dog'
debug_vars(['a', 'b', 'c']);
function debug_vars( $arr ) {
$display = array();
foreach($arr AS $v) {
GLOBAL ${$v};
$display[$v] = $v;
}
print_r($display);
}
I would like it to show an array of [ 'a' => 'test', 'b' => 'cat', 'c' => 'dog' ]

You are recreating the built in compact function, which already does what you want:
$a = 'test' ;
$b = 'cat' ;
$c = 'dog' ;
print_r(compact('a','b','c'));
//Array ( [a] => test [b] => cat [c] => dog )
http://php.net/manual/en/function.compact.php

You're almost there
$a = 'test';
$b = 'cat';
$c = 'dog' ;
debug_vars(['a', 'b', 'c']);
function debug_vars( $arr ) {
$display = array();
foreach($arr AS $v) {
GLOBAL ${$v};
$display[$v] = ${$v};
// ^---^--------------- use the global ?
}
print_r($display);
}
Output :
Array ( [a] => test [b] => cat [c] => dog )
Althought this is working as expected, I do not recommend you to use global variables. This may lead easily to unmaintainable code. Try using another approach than globals.

use $GLOBALS[]:
$display[$v] = $GLOBALS[$v];
-> http://php.net/manual/en/reserved.variables.globals.php
EDIT:
Using global $$v as mentioned in the other answers may have side effects if the var name is used locally.

You can use a variable variable with the $$ operator.
<?php
$a = 'test';
$b = 'cat';
$c = 'dog';
debug_vars(['a', 'b', 'c']);
function debug_vars( $arr ) {
$debug = array();
foreach($arr AS $v) {
if ($v != 'debug') {
GLOBAL $$v;
$debug[$v] = $$v;
}
}
print_r($debug);
}

Related

How can I get array like this

//I have array like below:
$a =array('1,2,6');
$b =array('2,3,1');
//Then I using ArrayCombine :
$arr_combine = array_combine( $a, $b );
//OUTPUT:
//Array( [1,2,6] => 2,3,1 ) ;
how can I get array like below?
//OUTPUT:
array( 1=>2, 2=>3, 6=>1 );
If you have the array like that, then you have to explode the element.
$result = array_combine(explode(',', $a[0]), explode(',', $b[0]));
It's taking as complete one string due to your present quotes in arrays,
Should be,
$a = array('1','2','6'); // And not '1,2,6'
$b = array('2','3','1');
$arr_combine = array_combine( $a, $b );
DEMO.
And if you can't change the array & have the format like that only see #xdazz answer.
For your second question check like this
<?php
$x = array( 1 => '2', 2 => '3', 6 => '1') ;
$y = array( 1 => '2', 6 => '2' ) ;
$s = array();
foreach($x as $key=>$val)
{
if (array_key_exists($key,$y))
{
$s[$key] = $x[$key] + $y[$key];
}
}
var_dump($s);
?>
Try like this
<?php
$a =array('1,2,6');
$b =array('2,3,1');
$a = explode(',',$a[0]);
$b = explode(',',$b[0]);
var_dump($a);
var_dump($b);
var_dump(array_combine($a,$b));
?>

Find all array keys that has same value

Is there a simpler way to get all array keys that has same value, when the value is unknown.
The problem with array_unique is that it returns the unique array and thus it doesn't find unique values.
That is, for example, from this array:
Array (
[a]=>1000
[b]=>1
[c]=>1000
)
I want to get this
Array (
[a]=>1000
[c]=>1000
)
Another way around this is, if I could find the lonely values, and then their keys, and then use array_diff
This is what I've got so far, looks awful:
$a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 );
$b = array_flip( array_count_values( $a ) );
krsort( $b );
$final = array_keys( $a, array_shift( $b ) );
Update
Using Paulo Freites' answer as a code base, I could get it working pretty easily, maintainable and easy on eyes kind of way… by using the filtering as a static class method I can get the duplicate values from an array by just calling ClassName::get_duplicates($array_to_filter)
private static $counts = null;
private static function filter_duplicates ($value) {
return self::$counts[ $value ] > 1;
}
public static function get_duplicates ($array) {
self::$counts = array_count_values( $array );
return array_filter( $array, 'ClassName::filter_duplicates' );
}
Taking advantage of closures for a more straightforward solution:
$array = array('a' => 1000, 'b' => 1, 'c' => 1000);
$counts = array_count_values($array);
$filtered = array_filter($array, function ($value) use ($counts) {
return $counts[$value] > 1;
});
var_dump($filtered);
This gave me the following:
array(2) {
["a"]=>
int(1000)
["c"]=>
int(1000)
}
Demo: https://eval.in/67526
That's all! :)
Update: backward-compatible solution
$array = array('a' => 1000, 'b' => 1, 'c' => 1000);
$counts = array_count_values($array);
$filtered = array_filter($array, create_function('$value',
'global $counts; return $counts[$value] > 1;'));
var_dump($filtered);
Demo: https://eval.in/68255
Your implementation has a few issues.
1) If there are 2 of value 1000 and 2 of another value, the array_flip will lose one of the sets of values.
2) If there are more than two different values, the array_keys will only find the one value that occurs most.
3) If there are no duplicates, you will still bring back one of the values.
Something like this works always and will return all duplicate values:
<?php
//the array
$a = array( 'a' => 1000, 'b' => 1, 'c' => 1000 );
//count of values
$cnt = array_count_values($a);
//a new array
$newArray = array();
//loop over existing array
foreach($a as $k=>$v){
//if the count for this value is more than 1 (meaning value has a duplicate)
if($cnt[$v] > 1){
//add to the new array
$newArray[$k] = $v;
}
}
print_r($newArray);
http://codepad.viper-7.com/fal5Yz
If you want to get the duplicates in an array try this:
array_unique(array_diff_assoc($array1, array_unique($array1)))
I found this from:
http://www.php.net/manual/en/function.array-unique.php#95203
at the moment I cant figure out another solution...
// target array
$your_array = array('a'=>1000, 'b'=>1, 'c'=>1000);
// function to do all the job
function get_duplicate_elements($array) {
$res = array();
$counts = array_count_values($array);
foreach ($counts as $id=>$count) {
if ($count > 1) {
$r = array();
$keys = array_keys($array, $id);
foreach ($keys as $k) $r[$k] = $id;
$res[] = $r;
}
}
return sizeof($res) > 0 ? $res : false;
}
// test it
print_r(get_duplicate_elements($your_array));
output:
Array
(
[0] => Array
(
[a] => 1000
[c] => 1000
)
)
example #2: - when you have different values multiplied
// target array
$your_array = array('a'=>1000, 'b'=>1, 'c'=>1000, 'd'=>500, 'e'=>1);
// output
print_r(get_duplicate_elements($your_array));
output:
Array
(
[0] => Array
(
[a] => 1000
[c] => 1000
)
[1] => Array
(
[b] => 1
[e] => 1
)
)
if function result has been assigned to $res variable $res[0] gets an array of all elements from original array with first value found more than once, $res[1] gets array of elements with another duplicated-value, etc... function returns false if nothing duplicate has been found in argument-array.
Try this
$a = array( 'a' => 1, 'b' => 1000, 'c' => 1000,'d'=>'duplicate','e'=>'duplicate','f'=>'ok','g'=>'ok' );
$b = array_map("unserialize", array_unique(array_map("serialize", $a)));
$c = array_diff_key($a, $b);
$array = array("1"=>"A","2"=>"A","3"=>"A","4"=>"B","5"=>"B","6"=>"B");
$val = array_unique(array_values($array));
foreach ($val As $v){
$dat[$v] = array_keys($array,$v);
}
print_r($dat);

How to set a deep array in PHP

Assume I have the following function
function setArray(&$array, $key, $value)
{
$array[$key] = $value;
}
In the above function, key is only at the first level, what if I want to set the key at the 2nd or 3rd levels, how to rewrite the function?
e.g.
$array['foo']['bar'] = 'test';
I want to use the same function to set the array value
This one should work. Using this function you can set any array element in any depth by passing a single string containing the keys separated by .
function setArray(&$array, $keys, $value) {
$keys = explode(".", $keys);
$current = &$array;
foreach($keys as $key) {
$current = &$current[$key];
}
$current = $value;
}
You can use this as follows:
$array = Array();
setArray($array, "key", Array('value' => 2));
setArray($array, "key.test.value", 3);
print_r($array);
output:
Array (
[key] => Array
(
[value] => 2
[test] => Array
(
[value] => 3
)
)
)
You can use array_merge_recursive
$array = array("A" => "B");
$new['foo']['bar'] = 'test';
setArray($array, $new);
var_dump($array);
Output
array (size=2)
'A' => string 'B' (length=1)
'foo' =>
array (size=1)
'bar' => string 'test' (length=4)
Function Used
function setArray(&$array, $value) {
$array = array_merge_recursive($array, $value);
}
this function should do it, the key should be an array, for example array('foo', 'bar')
function setArray(&$array, array $keys, $value) {
foreach($keys as $key) {
if(!isset($array[$key])) {
$array[$key] = array();
}
$array = &$array[$key];
}
$array = $value;
}
$arr = array();
setArray($arr, array('first', 'second'), 1);
var_dump($arr);
// dumps array(1) { ["first"]=> array(1) { ["second"]=> int(1) } }
Tested and works.
Use array_replace_recursive instead of array_merge_recursive as it handles same-key scenario correctly. See this https://3v4l.org/2ICmo
Just like this:
function setArray(&$array, $key1, $key2, $value)
{
$array[$key1][$key2] = $value;
}
But why you want to use function? Using it like this:
setArray($array, 'foo', 'bar', 'test');
takes more time to write something like this:
$array[1][2] = 'test';

Ordering PHP array by number of identical objects

Is there anyway to order an array in this way? For example if I had this array:
$array = array("foo", "bar", "item", "item", "foo", "foo");
And I wanted to order it so that it was "foo", "foo", "foo", "item", "item", "bar" is there any way to do that?
Would this do?
$array1 = array_count_values($array);
arsort($array1);
var_dump($array1);
will give you
array(3) {
["foo"]=>
int(3)
["item"]=>
int(2)
["bar"]=>
int(1)
}
or do you necessarily need them as repeated values? if yes, you may go for something like:
usort($array,create_function('$a,$b',
'return $GLOBALS["array1"][$a]<$GLOBALS["array1"][$b];'));
This is ugly code, but demonstrates the technique. It is also easy to make it good-looking with php 5.3 closures, but I don't know if you're on 5.3. That would look like this:
$acount=array_count_values($array = array("foo", "bar", "item", "item", "foo", "foo"));
usort($array,function($a,$b) use ($acount) { return $acount[$a]<$acount[$b]; });
First you have to count occurrence of each value (array_count_values), then use usort to sort element by your criteria:
<?php
$array = array('foo', 'bar', 'bar', 'foo', 'bar', 'foo', 'foobar', 'foo', 'foo', 'foobar', 'bar', 'foo');
$tmp = array_count_values($array);
usort($array, function($e1, $e2) use($tmp) {
return $tmp[$e2] - $tmp[$e1];
});
var_dump($array);
usort() could work. array_count_values() comes in handy though. With the calculations you need to make, this might be a little more clear and efficient . If there are a lot of repeated values (100+), you may also want to consider using array_fill() instead of the for loop:
function getSortedGroupArray($array) {
$return = array();
$values = array_count_values($array);
sort($values);
foreach($values as $count => $value) {
for($i = 0; $i < $count; ++$i) {
$return[] = $value;
}
}
return $return
}
That's quite and unusual sort process, it would be simplest to do as a two or three step process.
First count the different objects, then sort the object counts and generate from that the sorted object array.
Lets try this:
// First, lets count the number of objects
$sort_by_term = array();
foreach($array as $string)
{
if(isset($sort_by_term[$string]))
{
$sort_by_term[$string] += 1;
}
else
{
$sort_by_term[$string] = 1;
}
}
// Next let's sort them by number
$sort_by_count = array();
foreach($sort_by_term as $term => $count)
{
$sort_by_count[$count][] = $term;
}
// Now lets combine them
$final_array = array();
foreach($sort_by_count as $count => $term)
{
while($count > 0)
{
$final_array[] = $term;
$count -= 1;
}
}
Could be shortened using some of PHP's functions, but you get the idea of what has to be done.
You can use the following function for ordering by the frequency with which a value appears in an array:
function array_count_sort(&$array, $direction = 1)
{
// Could do with a better way of making $counts and $dir available to the
// sorting function, but this will do for illustrative purposes.
global $counts, $dir;
$counts = array_count_values($array);
$dir = $direction;
if (!function_exists('array_count_sort_cmp')) {
function array_count_sort_cmp($a, $b) {
global $counts, $dir;
$c = $counts[$a];
$d = $counts[$b];
if ($c == $d) return 0;
return ($c < $d) ? -$dir : $dir;
}
}
usort($array, 'array_count_sort_cmp');
}
And use it in the following way:
$test = array("foo", "bar", "item", "item", "foo", "foo");
print_r($test);
array_count_sort($test);
print_r($test);
array_count_sort($test, -1);
print_r($test);
which would yield
Array
(
[0] => foo
[1] => bar
[2] => item
[3] => item
[4] => foo
[5] => foo
)
Array
(
[0] => bar
[1] => item
[2] => item
[3] => foo
[4] => foo
[5] => foo
)
Array
(
[0] => foo
[1] => foo
[2] => foo
[3] => item
[4] => item
[5] => bar
)

Switch two items in associative array

Example:
$arr = array(
'apple' => 'sweet',
'grapefruit' => 'bitter',
'pear' => 'tasty',
'banana' => 'yellow'
);
I want to switch the positions of grapefruit and pear, so the array will become
$arr = array(
'apple' => 'sweet',
'pear' => 'tasty',
'grapefruit' => 'bitter',
'banana' => 'yellow'
)
I know the keys and values of the elements I want to switch, is there an easy way to do this? Or will it require a loop + creating a new array?
Thanks
Just a little shorter and less complicated than the solution of arcaneerudite:
<?php
if(!function_exists('array_swap_assoc')) {
function array_swap_assoc($key1, $key2, $array) {
$newArray = array ();
foreach ($array as $key => $value) {
if ($key == $key1) {
$newArray[$key2] = $array[$key2];
} elseif ($key == $key2) {
$newArray[$key1] = $array[$key1];
} else {
$newArray[$key] = $value;
}
}
return $newArray;
}
}
$array = $arrOrig = array(
'fruit' => 'pear',
'veg' => 'cucumber',
'tuber' => 'potato',
'meat' => 'ham'
);
$newArray = array_swap_assoc('veg', 'tuber', $array);
var_dump($array, $newArray);
?>
Tested and works fine
Here's my version of the swap function:
function array_swap_assoc(&$array,$k1,$k2) {
if($k1 === $k2) return; // Nothing to do
$keys = array_keys($array);
$p1 = array_search($k1, $keys);
if($p1 === FALSE) return; // Sanity check...keys must exist
$p2 = array_search($k2, $keys);
if($p2 === FALSE) return;
$keys[$p1] = $k2; // Swap the keys
$keys[$p2] = $k1;
$values = array_values($array);
// Swap the values
list($values[$p1],$values[$p2]) = array($values[$p2],$values[$p1]);
$array = array_combine($keys, $values);
}
if the array comes from the db, add a sort_order field so you can always be sure in what order the elements are in the array.
This may or may not be an option depending on your particular use-case, but if you initialize your array with null values with the appropriate keys before populating it with data, you can set the values in any order and the original key-order will be maintained. So instead of swapping elements, you can prevent the need to swap them entirely:
$arr = array('apple' => null,
'pear' => null,
'grapefruit' => null,
'banana' => null);
...
$arr['apple'] = 'sweet';
$arr['grapefruit'] = 'bitter'; // set grapefruit before setting pear
$arr['pear'] = 'tasty';
$arr['banana'] = 'yellow';
print_r($arr);
>>> Array
(
[apple] => sweet
[pear] => tasty
[grapefruit] => bitter
[banana] => yellow
)
Not entirely sure if this was mentioned, but, the reason this is tricky is because it's non-indexed.
Let's take:
$arrOrig = array(
'fruit'=>'pear',
'veg'=>'cucumber',
'tuber'=>'potato'
);
Get the keys:
$arrKeys = array_keys($arrOrig);
print_r($arrKeys);
Array(
[0]=>fruit
[1]=>veg
[2]=>tuber
)
Get the values:
$arrVals = array_values($arrOrig);
print_r($arrVals);
Array(
[0]=>pear
[1]=>cucumber
[2]=>potato
)
Now you've got 2 arrays that are numerical. Swap the indices of the ones you want to swap, then read the other array back in in the order of the modified numerical array. Let's say we want to swap 'fruit' and 'veg':
$arrKeysFlipped = array_flip($arrKeys);
print_r($arrKeysFlipped);
Array (
[fruit]=>0
[veg]=>1
[tuber]=>2
)
$indexFruit = $arrKeysFlipped['fruit'];
$indexVeg = $arrKeysFlipped['veg'];
$arrKeysFlipped['veg'] = $indexFruit;
$arrKeysFlipped['fruit'] = $indexVeg;
print_r($arrKeysFlipped);
Array (
[fruit]=>1
[veg]=>0
[tuber]=>2
)
Now, you can swap back the array:
$arrKeys = array_flip($arrKeysFlipped);
print_r($arrKeys);
Array (
[0]=>veg
[1]=>fruit
[2]=>tuber
)
Now, you can build an array by going through the oringal array in the 'order' of the rearranged keys.
$arrNew = array ();
foreach($arrKeys as $index=>$key) {
$arrNew[$key] = $arrOrig[$key];
}
print_r($arrNew);
Array (
[veg]=>cucumber
[fruit]=>pear
[tuber]=>potato
)
I haven't tested this - but this is what I'd expect. Does this at least provide any kind of help? Good luck :)
You could put this into a function $arrNew = array_swap_assoc($key1,$key2,$arrOld);
<?php
if(!function_exists('array_swap_assoc')) {
function array_swap_assoc($key1='',$key2='',$arrOld=array()) {
$arrNew = array ();
if(is_array($arrOld) && count($arrOld) > 0) {
$arrKeys = array_keys($arrOld);
$arrFlip = array_flip($arrKeys);
$indexA = $arrFlip[$key1];
$indexB = $arrFlip[$key2];
$arrFlip[$key1]=$indexB;
$arrFlip[$key2]=$indexA;
$arrKeys = array_flip($arrFlip);
foreach($arrKeys as $index=>$key) {
$arrNew[$key] = $arrOld[$key];
}
} else {
$arrNew = $arrOld;
}
return $arrNew;
}
}
?>
WARNING: Please test and debug this before just using it - no testing has been done at all.
There is no easy way, just a loop or a new array definition.
Classical associative array doesn't define or guarantee sequence of elements in any way. There is plain array/vector for that. If you use associative array you are assumed to need random access but not sequential. For me you are using assoc array for task it is not made for.
yeah I agree with Lex, if you are using an associative array to hold data, why not using your logic handle how they are accessed instead of depending on how they are arranged in the array.
If you really wanted to make sure they were in a correct order, trying creating fruit objects and then put them in a normal array.
There is no easy way to do this. This sounds like a slight design-logic error on your part which has lead you to try to do this when there is a better way to do whatever it is you are wanting to do. Can you tell us why you want to do this?
You say that I know the keys and values of the elements I want to switch which makes me think that what you really want is a sorting function since you can easily access the proper elements anytime you want as they are.
$value = $array[$key];
If that is the case then I would use sort(), ksort() or one of the many other sorting functions to get the array how you want. You can even use usort() to Sort an array by values using a user-defined comparison function.
Other than that you can use array_replace() if you ever need to swap values or keys.
Here are two solutions. The first is longer, but doesn't create a temporary array, so it saves memory. The second probably runs faster, but uses more memory:
function swap1(array &$a, $key1, $key2)
{
if (!array_key_exists($key1, $a) || !array_key_exists($key2, $a) || $key1 == $key2) return false;
$after = array();
while (list($key, $val) = each($a))
{
if ($key1 == $key)
{
break;
}
else if ($key2 == $key)
{
$tmp = $key1;
$key1 = $key2;
$key2 = $tmp;
break;
}
}
$val1 = $a[$key1];
$val2 = $a[$key2];
while (list($key, $val) = each($a))
{
if ($key == $key2)
$after[$key1] = $val1;
else
$after[$key] = $val;
unset($a[$key]);
}
unset($a[$key1]);
$a[$key2] = $val2;
while (list($key, $val) = each($after))
{
$a[$key] = $val;
unset($after[$key]);
}
return true;
}
function swap2(array &$a, $key1, $key2)
{
if (!array_key_exists($key1, $a) || !array_key_exists($key2, $a) || $key1 == $key2) return false;
$swapped = array();
foreach ($a as $key => $val)
{
if ($key == $key1)
$swapped[$key2] = $a[$key2];
else if ($key == $key2)
$swapped[$key1] = $a[$key1];
else
$swapped[$key] = $val;
}
$a = $swapped;
return true;
}
fwiw here is a function to swap two adjacent items to implement moveUp() or moveDown() in an associative array without foreach()
/**
* #param array $array to modify
* #param string $key key to move
* #param int $direction +1 for down | -1 for up
* #return $array
*/
protected function moveInArray($array, $key, $direction = 1)
{
if (empty($array)) {
return $array;
}
$keys = array_keys($array);
$index = array_search($key, $keys);
if ($index === false) {
return $array; // not found
}
if ($direction < 0) {
$index--;
}
if ($index < 0 || $index >= count($array) - 1) {
return $array; // at the edge: cannot move
}
$a = $keys[$index];
$b = $keys[$index + 1];
$result = array_slice($array, 0, $index, true);
$result[$b] = $array[$b];
$result[$a] = $array[$a];
return array_merge($result, array_slice($array, $index + 2, null, true));
}
There is an easy way:
$sourceArray = array(
'apple' => 'sweet',
'grapefruit' => 'bitter',
'pear' => 'tasty',
'banana' => 'yellow'
);
// set new order
$orderArray = array(
'apple' => '', //this values would be replaced
'pear' => '',
'grapefruit' => '',
//it is not necessary to touch all elemets that will remains the same
);
$result = array_replace($orderArray, $sourceArray);
print_r($result);
and you get:
$result = array(
'apple' => 'sweet',
'pear' => 'tasty',
'grapefruit' => 'bitter',
'banana' => 'yellow'
)
function arr_swap_keys(array &$arr, $key1, $key2, $f_swap_vals=false) {
// if f_swap_vals is false, then
// swap only the keys, keeping the original values in their original place
// ( i.e. do not preserve the key value correspondence )
// i.e. if arr is (originally)
// [ 'dog' => 'alpha', 'cat' => 'beta', 'horse' => 'gamma' ]
// then calling this on arr with, e.g. key1 = 'cat', and key2 = 'horse'
// will result in arr becoming:
// [ 'dog' => 'alpha', 'horse' => 'beta', 'cat' => 'gamma' ]
//
// if f_swap_vals is true, then preserve the key value correspondence
// i.e. in the above example, arr will become:
// [ 'dog' => 'alpha', 'horse' => 'gamma', 'cat' => 'beta' ]
//
//
$arr_vals = array_values($arr); // is a (numerical) index to value mapping
$arr_keys = array_keys($arr); // is a (numerical) index to key mapping
$arr_key2idx = array_flip($arr_keys);
$idx1 = $arr_key2idx[$key1];
$idx2 = $arr_key2idx[$key2];
swap($arr_keys[$idx1], $arr_keys[$idx2]);
if ( $f_swap_vals ) {
swap($arr_vals[$idx1], $arr_vals[$idx2]);
}
$arr = array_combine($arr_keys, $arr_vals);
}
function swap(&$a, &$b) {
$t = $a;
$a = $b;
$b = $t;
}
Well it's just a key sorting problem. We can use uksort for this purpose. It needs a key comparison function and we only need to know that it should return 0 to leave keys position untouched and something other than 0 to move key up or down.
Notice that it will only work if your keys you want to swap are next to each other.
<?php
$arr = array(
'apple' => 'sweet',
'grapefruit' => 'bitter',
'pear' => 'tasty',
'banana' => 'yellow'
);
uksort(
$arr,
function ($k1, $k2) {
if ($k1 == 'grapefruit' && $k2 == 'pear') return 1;
else return 0;
}
);
var_dump($arr);
I'll share my short version too, it works with both numeric and associative arrays.
array array_swap ( array $array , mixed $key1 , mixed $key2 [, bool $preserve_keys = FALSE [, bool $strict = FALSE ]] )
Returns a new array with the two elements swapped. It preserve original keys if specified. Return FALSE if keys are not found.
function array_swap(array $array, $key1, $key2, $preserve_keys = false, $strict = false) {
$keys = array_keys($array);
if(!array_key_exists($key1, $array) || !array_key_exists($key2, $array)) return false;
if(($index1 = array_search($key1, $keys, $strict)) === false) return false;
if(($index2 = array_search($key2, $keys, $strict)) === false) return false;
if(!$preserve_keys) list($keys[$index1], $keys[$index2]) = array($key2, $key1);
list($array[$key1], $array[$key2]) = array($array[$key2], $array[$key1]);
return array_combine($keys, array_values($array));
}
For example:
$arr = array_swap($arr, 'grapefruit', 'pear');
I wrote a function with more general purpose, with this problem in mind.
array with known keys
specify order of keys in a second array ($order array keys indicate key position)
function order_array($array, $order) {
foreach (array_keys($array) as $k => $v) {
$keys[++$k] = $v;
}
for ($i = 1; $i <= count($array); $i++) {
if (isset($order[$i])) {
unset($keys[array_search($order[$i], $keys)]);
}
if ($i === count($array)) {
array_push($keys, $order[$i]);
} else {
array_splice($keys, $i-1, 0, $order[$i]);
}
}
}
foreach ($keys as $key) {
$result[$key] = $array[$key];
}
return $result;
} else {
return false;
}
}
$order = array(1 => 'item3', 2 => 'item5');
$array = array("item1" => 'val1', "item2" => 'val2', "item3" => 'val3', "item4" => 'val4', "item5" => 'val5');
print_r($array); -> Array ( [item1] => val1 [item2] => val2 [item3] => val3 [item4] => val4 [item5] => val5 )
print_r(order_array($array, $order)); -> Array ( [item3] => val3 [item5] => val5 [item1] => val1 [item2] => val2 [item4] => val4 )
I hope this is relevant / helpful for someone
Arrays in php are ordered maps.
$arr = array('apple'=>'sweet','grapefruit'=>'bitter','
pear'=>'tasty','banana'=>'yellow');
doesn't mean that that the first element is 'apple'=>'sweet' and the last - 'banana'=>'yellow' just because you put 'apple' first and 'banana' last. Actually, 'apple'=>'sweet' will be the first and
'banana'=>'yellow' will be the second because of alphabetical ascending sort order.

Categories