Check for key-value pair in multidimensional array - php

I have the follow array:
Array
(
[0] => Array
(
[type] => foo
)
[1] => Array
(
[type] => bar
)
[2] => Array
(
[type] => bar
)
)
and need to know if exists one or more type which value is bar, without do this:
foreach ($arrayOfTypes as $type) {
if ($type['type'] == 'bar')
{
// Stuff here
}
}
(Only for learning purposes)

I'd go with array_filter();
$filteredArray = array_filter($stuff, function($item){
return $item['type'] == 'bar';
});
if( count($filteredArray) > 0 ){
echo 'There was a bar item in array.';
}else{
echo 'No luck sorry!';
}

Use in_array: http://se.php.net/manual/en/function.in-array.php
Combine it with array_map to flatten what you have. Like so:
$new_array = array_map( function( $arr ) {
return $arr['type'];
}, $array );
in_array( 'bar', $new_array );

Honestly a foreach loop or moonwave99's array-filter answer is probably going to be your best bet, but if what you're looking is the shortest code possible and creativity that will make most programmers gag, you could try serialize-ing the array and using string-searching functions:
serialize(array(
0=>array(
'type' => 'foo'
),
1=>array(
'type' => 'bar'
),
2=>array(
'type' => 'bar'
)
))
becomes
a:3:{i:0;a:1:{s:4:"type";s:3:"foo";}i:1;a:1:{s:4:"type";s:3:"bar";}i:2;a:1:{s:4:"type";s:3:"bar";}}
So you can now run a strpos() or preg_match() function to find them. So your whole function would look like:
$exists = strpos('{s:4:"type";s:3:"bar";}',serialize($arrayOfTypes)); //returns number or false
It's short, it's snappy, and get's the job done for simple string keypairs.

This is basically the same as moonwave99's solution but slightly more useful as it's in a function that you can feed a key/value pair to as well, so it can be used to search for any key/value combo:
function isKVInArray($k, $v, $array) {
$filtered = array_filter($array, function($item) use($k,$v) {
return $item[$k] == $v;
});
if(count($filtered)>=1) return true;
else return false;
}
$k = 'live';
$v = 'y';
$my_array = array(
0=>array(
'live'=>'n',
'something_else'=>'a'
),
1=>array(
'live'=>'y',
'something_else'=>'b'
),
2=>array(
'live'=>'n',
'something_else'=>'c'
)
);
if(isKVInArray($k, $v, $my_array)) echo "$k=>$v was found in the array.";
else echo 'No luck sorry!';

there's another simple way which is useful when you need to count all the different values
foreach ($arrayOfTypes as $type) $cnt[$type['type']]++;
To get the number of 'bar' (or to get the count of another value):
echo($cnt['bar']);

Related

Searching an array of associate arrays for two matching parameters

I have a loop that builds an array of associative arrays that looks like this:
array(
'foo' => '',
'bar' => '',
'thingys' => array()
)
on each iteration of the loop, I want to search through the array for an associate array that's 'foo' and 'bar' properties match those of the current associate array. If it exists I want to append the thingys property of the current associative array to the match. Otherwise append the entire thing.
I know how to do this with for loops, but I'm wondering if there is a simpler way to do this with an array function. I'm on php 5.3.
Example
<?php
$arr = array(
array(
'foo' => 1,
'bar' => 2,
'thing' => 'apple'
),
array(
'foo' => 1,
'bar' => 2,
'thing' => 'orange'
),
array(
'foo' => 2,
'bar' => 2,
'thing' => 'apple'
),
);
$newArr = array();
for ($i=0; $i < count($arr); $i++) {
$matchFound = false;
for ($j=0; $j < count($newArr); $j++) {
if ($arr[$i]['foo'] === $newArr[$j]['foo'] && $arr[$i]['bar'] === $newArr[$j]['bar']) {
array_push($newArr[$j]['thing'], $arr[$i]['things']);
$matchFound = true;
break;
}
}
if (!$matchFound) {
array_push($newArr,
array(
'foo' => $arr[$i]['foo'],
'bar' => $arr[$i]['bar'],
'things' => array($arr[$i]['thing'])
)
);
}
}
/*Output
$newArr = array(
array(
'foo' => 1,
'bar' => 2,
'things' => array('orange', 'apple')
),
array(
'foo' => 2,
'bar' => 2,
'things' => array('apple')
),
)
*/
?>
I don't know if it is possible through a built-in function, but I think no. Something can be implemented through array_map, but anyway you have to perform a double loop.
I propose you a one-loop solution using a temporary array ($keys) as index of already created $newArr items, based on foo and bar; elements of original array are processed through a foreach loop, and if a $keys element with first key as foo value and second key as bar value exists, then the current thing value is added to the returned key index of $newArr, otherwise a new $newArray element is created.
$newArr = $keys = array();
foreach( $arr as $row )
{
if( isset( $keys[$row['foo']][$row['bar']] ) )
{ $newArr[$keys[$row['foo']][$row['bar']]]['thing'][] = $row['thing']; }
else
{
$keys[$row['foo']][$row['bar']] = array_push( $newArr, $row )-1;
$newArr[$keys[$row['foo']][$row['bar']]]['thing'] = array( $row['thing'] );
}
}
unset( $keys );
3v4l.org demo
Edit: array_map variant
This is the same solution above, using array_map instead of foreach loop. Note that also your original code can be converted in this way.
$newArr = $keys = array();
function filterArr( $row )
{
global $newArr, $keys;
if( isset( $keys[$row['foo']][$row['bar']] ) )
{ $newArr[$keys[$row['foo']][$row['bar']]]['thing'][] = $row['thing']; }
else
{
$keys[$row['foo']][$row['bar']] = array_push( $newArr, $row )-1;
$newArr[$keys[$row['foo']][$row['bar']]]['thing'] = array( $row['thing'] );
}
}
array_map( 'filterArr', $arr );
3v4l.org demo

Build multidimensional array from an array in PHP

I would like to build a multidimensional array from an array. For example I would like
$test = array (
0 => 'Tree',
1 => 'Trunk',
2 => 'Branch',
3 => 'Limb',
4 => 'Apple',
5 => 'Seed'
);
to become
$test =
array (
'Tree' => array (
'Trunk' => array (
'Branch' => array (
'Limb' => array (
'Apple' => array (
'Seed' => array ()
)
)
)
)
)
);
or more simply
$result[Tree][Trunk][Branch][Limb][Apple][Seed] = null;
I'm trying to do this with a recursive function but i'm hitting memory limit so I'm clearly doing it wrong.
<?php
$test = array (
0 => 'Tree',
1 => 'Trunk',
2 => 'Branch',
3 => 'Limb',
4 => 'Apple',
5 => 'Seed'
);
print_r($test);
print "results of function";
print_r(buildArray($test));
function buildArray (&$array, &$build = null)
{
if (count($array) > 0)
{
//create an array, pass the array to itself removing the first value
$temp = array_values($array);
unset ($temp[0]);
$build[$array[0]] = $temp;
buildArray($build,$temp);
return $build;
}
return $build;
}
Here's an approach with foreach and without recursion, which works:
function buildArray($array)
{
$new = array();
$current = &$new;
foreach($array as $key => $value)
{
$current[$value] = array();
$current = &$current[$value];
}
return $new;
}
[ Demo ]
Now your function... first, using $build[$array[0]] without defining it as an array first produces an E_NOTICE.
Second, your function is going into infinite recursion because you are not actually modifying $array ($temp isn't the same), so count($array) > 0 will be true for all of eternity.
And even if you were modifying $array, you couldn't use $array[0] anymore, because you unset that, and the indices don't just slide up. You would need array_shift for that.
After that, you pass $build and $temp to your function, which results in further because you now you assign $build to $temp, therefore creating another loop in your already-infinitely-recurring loop.
I was trying to fix all of the above in your code, but eventually realized that my code was now pretty much exactly the one from Pevara's answer, just with different variable names, so... that's that.
This function works recursively and does the trick:
function buildArray($from, $to = []) {
if (empty($from)) { return null; }
$to[array_shift($from)] = buildArray($from, $to);
return $to;
}
In your code I would expect you see an error. You are talking to $build in your first iteration as if it where an array, while you have defaulted it to null.
It seems to be easy
$res = array();
$i = count($test);
while ($i)
$res = array($test[--$i] => $res);
var_export($res);
return
array ( 'Tree' => array ( 'Trunk' => array ( 'Branch' => array ( 'Limb' => array ( 'Apple' => array ( 'Seed' => array ( ), ), ), ), ), ), )
Using a pointer, keep re-pointing it deeper. Your two output examples gave array() and null for the deepest value; this gives array() but if you want null, replace $p[$value] = array(); with $p[$value] = $test ? array() : null;
$test = array(
'Tree',
'Trunk',
'Branch',
'Limb',
'Apple',
'Seed'
);
$output = array();
$p = &$output;
while ($test) {
$value = array_shift($test);
$p[$value] = array();
$p = &$p[$value];
}
print_r($output);

Accessing a PHP array

I'm sure this has been asked before, but I can't seem to find the answer.
To that end, I have an array that looks like this:
Array
(
[0] => Array
(
[status] => active
[sid] => 1
)
[1] => Array
(
[status] => expired
[sid] => 2
)
)
What I'd like to be able to do is type $arrayName["active"] and it return the SID code. I will be using this like a dictionary object of sorts. It's like I need to reindex the array so that it is the key/value pair that I need. I was just wondering if there was an easier way to do it.
You should convert your nested arrays into a single associative array. Something like this should take your example and turn it into an associative array:
$assoc_array = array();
foreach( $example_array as $values ) {
$assoc_array[$values["status"]] = $values["sid"];
}
You can then access the sid for a given status by using $assoc_array["expired"] (returns 2)
After seeing the others' solutions, I realize this might be bit of an overkill, but I'm still just gonna throw it out there:
$foo = array(
array('status' => 'active', 'sid' => 1),
array('status' => 'expired', 'sid' => 2),
);
// Get all the 'status' elements of each subarray
$keys = array_map(function($element) {
return $element['status'];
}, $foo);
// Get all the 'sid' elements of each subarray
$values = array_map(function($element) {
return $element['sid'];
}, $foo);
// Combine them into a single array, with keys from one and values from another
$bar = array_combine($keys, $values);
print_r($bar);
Which prints:
Array
(
[active] => 1
[expired] => 2
)
Manual pages:
array_map()
array_keys()
array_values()
array_combine()
Anonymous functions
You can use this function:
function findActive($my_array){
foreach($my_array as $array){
foreach($array as $val){
if($val['status']==='active'){
return $val['sid'];
}
}
}
return false;
}
access it via a loop or directly.
if($arrayName[0]['status'] == "active") {
echo $arrayName[0]['sid'];
}
If you want to check all the SIDs
foreach($arrayName as $item) {
if($item['status'] == "active") {
echo $item['sid'];
}
}
A more direct approach is just putting the loop in a function and return an array of all active session IDs
$sidArr = array();
foreach($yourArr as $val) {
if("active" == $val["status"]) {
array_push($sidArr, $val["sid"]);
}
}
reindex would be the best
$arrayName = array()
foreach ($data_array as $data)
$arrayName[$data['status']]=$data['sid'];
Or use a function
function get_sid($status)
{
global $data_array;
foreach ($data_array as $data) {
if ($data['status']==$status)
return $data['sid'];
}
return false;
}

Find Value in Array

The following array is output from my db.
$this->db->select('code')->from('table');
$array = $this->db->get()->result_array();
//Output:
Array ( [0] => Array ( [code] => ASDF123 ) [1] => Array ( [code] => ASDF124 ) )
How can I find if a variable is contained in this array?
ie.
if(this_is_in_array($value, $array) == TRUE)...
What's the simplest way to to that with PHP?
I sincerely apologize for not wording this correctly the first time.
In case you wish to find the KEY of an array you would refer to the array_key_exists() method.
An example of this would be:
$array = array(
'key1' => 'value1',
'key2' => 'value2'
);
if ( array_key_exists( 'key2', $array ) )
return TRUE;
If you would however prefer to find the VALUE of an array, you would refer to the in_array() method. An example of this would be:
$array = array(
'key1' => 'value1',
'key2' => 'value2'
);
if ( in_array( 'value1', $array ) )
return TRUE;
Kevin:
foreach( $array as $key => $values )
{
if ( $values['code'] == 'ASD1234' )
{
// do something
}
}
make your array this:
$your_array = array('key1'=>'value1', 'key2'=>'value2');
then use this to see if the key exists in the array.
if (array_key_exists('key2', $your_array)) {
Unsure about what exactly you mean in your question, however, to answer your question title, you can use the array_key_exists() function to check if a given key or index exists within an array.
put your validation into the function
$input = 'ASDF123';
function check_input($input) {
$array = array(
0 => array('code' => 'ASDF123'),
1 => array('code' => 'ASDF124')
);
foreach ($array as $codes) {
if (in_array($input, $codes)) {
return true;
}
}
return false;
}
$needle = 'ASDF123';
$ary = Array(
Array('code' => 'ASDF123'),
Array('code' => 'ASDF124')
);
$_ = "return (\$a['code']='".addslashes($needle)."');";
if (count(array_filter($ary[0],create_function('$a',$_))) > 0)
//true
I THINK (only because you use code twice, so I assume that's not the search field--or it's a semantics issue). If it is semantics, as everyone else has already suggested, try array_key_exists.

Replace keys in an array based on another lookup/mapping array

I have an associative array in the form key => value where key is a numerical value, however it is not a sequential numerical value. The key is actually an ID number and the value is a count. This is fine for most instances, however I want a function that gets the human-readable name of the array and uses that for the key, without changing the value.
I didn't see a function that does this, but I'm assuming I need to provide the old key and new key (both of which I have) and transform the array. Is there an efficient way of doing this?
$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);
The way you would do this and preserve the ordering of the array is by putting the array keys into a separate array, find and replace the key in that array and then combine it back with the values.
Here is a function that does just that:
function change_key( $array, $old_key, $new_key ) {
if( ! array_key_exists( $old_key, $array ) )
return $array;
$keys = array_keys( $array );
$keys[ array_search( $old_key, $keys ) ] = $new_key;
return array_combine( $keys, $array );
}
if your array is built from a database query, you can change the key directly from the mysql statement:
instead of
"select ´id´ from ´tablename´..."
use something like:
"select ´id´ **as NEWNAME** from ´tablename´..."
The answer from KernelM is nice, but in order to avoid the issue raised by Greg in the comment (conflicting keys), using a new array would be safer
$newarr[$newkey] = $oldarr[$oldkey];
$oldarr=$newarr;
unset($newarr);
$array = [
'old1' => 1
'old2' => 2
];
$renameMap = [
'old1' => 'new1',
'old2' => 'new2'
];
$array = array_combine(array_map(function($el) use ($renameMap) {
return $renameMap[$el];
}, array_keys($array)), array_values($array));
/*
$array = [
'new1' => 1
'new2' => 2
];
*/
You could use a second associative array that maps human readable names to the id's. That would also provide a Many to 1 relationship. Then do something like this:
echo 'Widgets: ' . $data[$humanreadbleMapping['Widgets']];
If you want also the position of the new array key to be the same as the old one you can do this:
function change_array_key( $array, $old_key, $new_key) {
if(!is_array($array)){ print 'You must enter a array as a haystack!'; exit; }
if(!array_key_exists($old_key, $array)){
return $array;
}
$key_pos = array_search($old_key, array_keys($array));
$arr_before = array_slice($array, 0, $key_pos);
$arr_after = array_slice($array, $key_pos + 1);
$arr_renamed = array($new_key => $array[$old_key]);
return $arr_before + $arr_renamed + $arr_after;
}
Simple benchmark comparison of both solution.
Solution 1 Copy and remove (order lost, but way faster) https://stackoverflow.com/a/240676/1617857
<?php
$array = ['test' => 'value', ['etc...']];
$array['test2'] = $array['test'];
unset($array['test']);
Solution 2 Rename the key https://stackoverflow.com/a/21299719/1617857
<?php
$array = ['test' => 'value', ['etc...']];
$keys = array_keys( $array );
$keys[array_search('test', $keys, true)] = 'test2';
array_combine( $keys, $array );
Benchmark:
<?php
$array = ['test' => 'value', ['etc...']];
for ($i =0; $i < 100000000; $i++){
// Solution 1
}
for ($i =0; $i < 100000000; $i++){
// Solution 2
}
Results:
php solution1.php 6.33s user 0.02s system 99% cpu 6.356 total
php solution1.php 6.37s user 0.01s system 99% cpu 6.390 total
php solution2.php 12.14s user 0.01s system 99% cpu 12.164 total
php solution2.php 12.57s user 0.03s system 99% cpu 12.612 total
If your array is recursive you can use this function:
test this data:
$datos = array
(
'0' => array
(
'no' => 1,
'id_maquina' => 1,
'id_transaccion' => 1276316093,
'ultimo_cambio' => 'asdfsaf',
'fecha_ultimo_mantenimiento' => 1275804000,
'mecanico_ultimo_mantenimiento' =>'asdfas',
'fecha_ultima_reparacion' => 1275804000,
'mecanico_ultima_reparacion' => 'sadfasf',
'fecha_siguiente_mantenimiento' => 1275804000,
'fecha_ultima_falla' => 0,
'total_fallas' => 0,
),
'1' => array
(
'no' => 2,
'id_maquina' => 2,
'id_transaccion' => 1276494575,
'ultimo_cambio' => 'xx',
'fecha_ultimo_mantenimiento' => 1275372000,
'mecanico_ultimo_mantenimiento' => 'xx',
'fecha_ultima_reparacion' => 1275458400,
'mecanico_ultima_reparacion' => 'xx',
'fecha_siguiente_mantenimiento' => 1275372000,
'fecha_ultima_falla' => 0,
'total_fallas' => 0,
)
);
here is the function:
function changekeyname($array, $newkey, $oldkey)
{
foreach ($array as $key => $value)
{
if (is_array($value))
$array[$key] = changekeyname($value,$newkey,$oldkey);
else
{
$array[$newkey] = $array[$oldkey];
}
}
unset($array[$oldkey]);
return $array;
}
I like KernelM's solution, but I needed something that would handle potential key conflicts (where a new key may match an existing key). Here is what I came up with:
function swapKeys( &$arr, $origKey, $newKey, &$pendingKeys ) {
if( !isset( $arr[$newKey] ) ) {
$arr[$newKey] = $arr[$origKey];
unset( $arr[$origKey] );
if( isset( $pendingKeys[$origKey] ) ) {
// recursion to handle conflicting keys with conflicting keys
swapKeys( $arr, $pendingKeys[$origKey], $origKey, $pendingKeys );
unset( $pendingKeys[$origKey] );
}
} elseif( $newKey != $origKey ) {
$pendingKeys[$newKey] = $origKey;
}
}
You can then cycle through an array like this:
$myArray = array( '1970-01-01 00:00:01', '1970-01-01 00:01:00' );
$pendingKeys = array();
foreach( $myArray as $key => $myArrayValue ) {
// NOTE: strtotime( '1970-01-01 00:00:01' ) = 1 (a conflicting key)
$timestamp = strtotime( $myArrayValue );
swapKeys( $myArray, $key, $timestamp, $pendingKeys );
}
// RESULT: $myArray == array( 1=>'1970-01-01 00:00:01', 60=>'1970-01-01 00:01:00' )
Here is a helper function to achieve that:
/**
* Helper function to rename array keys.
*/
function _rename_arr_key($oldkey, $newkey, array &$arr) {
if (array_key_exists($oldkey, $arr)) {
$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);
return TRUE;
} else {
return FALSE;
}
}
pretty based on #KernelM answer.
Usage:
_rename_arr_key('oldkey', 'newkey', $my_array);
It will return true on successful rename, otherwise false.
this code will help to change the oldkey to new one
$i = 0;
$keys_array=array("0"=>"one","1"=>"two");
$keys = array_keys($keys_array);
for($i=0;$i<count($keys);$i++) {
$keys_array[$keys_array[$i]]=$keys_array[$i];
unset($keys_array[$i]);
}
print_r($keys_array);
display like
$keys_array=array("one"=>"one","two"=>"two");
Easy stuff:
this function will accept the target $hash and $replacements is also a hash containing newkey=>oldkey associations.
This function will preserve original order, but could be problematic for very large (like above 10k records) arrays regarding performance & memory.
function keyRename(array $hash, array $replacements) {
$new=array();
foreach($hash as $k=>$v)
{
if($ok=array_search($k,$replacements))
$k=$ok;
$new[$k]=$v;
}
return $new;
}
this alternative function would do the same, with far better performance & memory usage, at the cost of losing original order (which should not be a problem since it is hashtable!)
function keyRename(array $hash, array $replacements) {
foreach($hash as $k=>$v)
if($ok=array_search($k,$replacements))
{
$hash[$ok]=$v;
unset($hash[$k]);
}
return $hash;
}
This page has been peppered with a wide interpretation of what is required because there is no minimal, verifiable example in the question body. Some answers are merely trying to solve the "title" without bothering to understand the question requirements.
The key is actually an ID number and the value is a count. This is
fine for most instances, however I want a function that gets the
human-readable name of the array and uses that for the key, without
changing the value.
PHP keys cannot be changed but they can be replaced -- this is why so many answers are advising the use of array_search() (a relatively poor performer) and unset().
Ultimately, you want to create a new array with names as keys relating to the original count. This is most efficiently done via a lookup array because searching for keys will always outperform searching for values.
Code: (Demo)
$idCounts = [
3 => 15,
7 => 12,
8 => 10,
9 => 4
];
$idNames = [
1 => 'Steve',
2 => 'Georgia',
3 => 'Elon',
4 => 'Fiona',
5 => 'Tim',
6 => 'Petra',
7 => 'Quentin',
8 => 'Raymond',
9 => 'Barb'
];
$result = [];
foreach ($idCounts as $id => $count) {
if (isset($idNames[$id])) {
$result[$idNames[$id]] = $count;
}
}
var_export($result);
Output:
array (
'Elon' => 15,
'Quentin' => 12,
'Raymond' => 10,
'Barb' => 4,
)
This technique maintains the original array order (in case the sorting matters), doesn't do any unnecessary iterating, and will be very swift because of isset().
If you want to replace several keys at once (preserving order):
/**
* Rename keys of an array
* #param array $array (asoc)
* #param array $replacement_keys (indexed)
* #return array
*/
function rename_keys($array, $replacement_keys) {
return array_combine($replacement_keys, array_values($array));
}
Usage:
$myarr = array("a" => 22, "b" => 144, "c" => 43);
$newkeys = array("x","y","z");
print_r(rename_keys($myarr, $newkeys));
//must return: array("x" => 22, "y" => 144, "z" => 43);
You can use this function based on array_walk:
function mapToIDs($array, $id_field_name = 'id')
{
$result = [];
array_walk($array,
function(&$value, $key) use (&$result, $id_field_name)
{
$result[$value[$id_field_name]] = $value;
}
);
return $result;
}
$arr = [0 => ['id' => 'one', 'fruit' => 'apple'], 1 => ['id' => 'two', 'fruit' => 'banana']];
print_r($arr);
print_r(mapToIDs($arr));
It gives:
Array(
[0] => Array(
[id] => one
[fruit] => apple
)
[1] => Array(
[id] => two
[fruit] => banana
)
)
Array(
[one] => Array(
[id] => one
[fruit] => apple
)
[two] => Array(
[id] => two
[fruit] => banana
)
)
This basic function handles swapping array keys and keeping the array in the original order...
public function keySwap(array $resource, array $keys)
{
$newResource = [];
foreach($resource as $k => $r){
if(array_key_exists($k,$keys)){
$newResource[$keys[$k]] = $r;
}else{
$newResource[$k] = $r;
}
}
return $newResource;
}
You could then loop through and swap all 'a' keys with 'z' for example...
$inputs = [
0 => ['a'=>'1','b'=>'2'],
1 => ['a'=>'3','b'=>'4']
]
$keySwap = ['a'=>'z'];
foreach($inputs as $k=>$i){
$inputs[$k] = $this->keySwap($i,$keySwap);
}
This function will rename an array key, keeping its position, by combining with index searching.
function renameArrKey($arr, $oldKey, $newKey){
if(!isset($arr[$oldKey])) return $arr; // Failsafe
$keys = array_keys($arr);
$keys[array_search($oldKey, $keys)] = $newKey;
$newArr = array_combine($keys, $arr);
return $newArr;
}
Usage:
$arr = renameArrKey($arr, 'old_key', 'new_key');
this works for renaming the first key:
$a = ['catine' => 'cat', 'canine' => 'dog'];
$tmpa['feline'] = $a['catine'];
unset($a['catine']);
$a = $tmpa + $a;
then, print_r($a) renders a repaired in-order array:
Array
(
[feline] => cat
[canine] => dog
)
this works for renaming an arbitrary key:
$a = ['canine' => 'dog', 'catine' => 'cat', 'porcine' => 'pig']
$af = array_flip($a)
$af['cat'] = 'feline';
$a = array_flip($af)
print_r($a)
Array
(
[canine] => dog
[feline] => cat
[porcine] => pig
)
a generalized function:
function renameKey($oldkey, $newkey, $array) {
$val = $array[$oldkey];
$tmp_A = array_flip($array);
$tmp_A[$val] = $newkey;
return array_flip($tmp_A);
}
There is an alternative way to change the key of an array element when working with a full array - without changing the order of the array.
It's simply to copy the array into a new array.
For instance, I was working with a mixed, multi-dimensional array that contained indexed and associative keys - and I wanted to replace the integer keys with their values, without breaking the order.
I did so by switching key/value for all numeric array entries - here: ['0'=>'foo']. Note that the order is intact.
<?php
$arr = [
'foo',
'bar'=>'alfa',
'baz'=>['a'=>'hello', 'b'=>'world'],
];
foreach($arr as $k=>$v) {
$kk = is_numeric($k) ? $v : $k;
$vv = is_numeric($k) ? null : $v;
$arr2[$kk] = $vv;
}
print_r($arr2);
Output:
Array (
[foo] =>
[bar] => alfa
[baz] => Array (
[a] => hello
[b] => world
)
)
best way is using reference, and not using unset (which make another step to clean memory)
$tab = ['two' => [] ];
solution:
$tab['newname'] = & $tab['two'];
you have one original and one reference with new name.
or if you don't want have two names in one value is good make another tab and foreach on reference
foreach($tab as $key=> & $value) {
if($key=='two') {
$newtab["newname"] = & $tab[$key];
} else {
$newtab[$key] = & $tab[$key];
}
}
Iterration is better on keys than clone all array, and cleaning old array if you have long data like 100 rows +++ etc..
One which preservers ordering that's simple to understand:
function rename_array_key(array $array, $old_key, $new_key) {
if (!array_key_exists($old_key, $array)) {
return $array;
}
$new_array = [];
foreach ($array as $key => $value) {
$new_key = $old_key === $key
? $new_key
: $key;
$new_array[$new_key] = $value;
}
return $new_array;
}
Here is an experiment (test)
Initial array (keys like 0,1,2)
$some_array[] = '6110';//
$some_array[] = '6111';//
$some_array[] = '6210';//
I must change key names to for example human_readable15, human_readable16, human_readable17
Something similar as already posted. During each loop i set necessary key name and remove corresponding key from the initial array.
For example, i inserted into mysql $some_array got lastInsertId and i need to send key-value pair back to jquery.
$first_id_of_inserted = 7;//lastInsertId
$last_loop_for_some_array = count($some_array);
for ($current_loop = 0; $current_loop < $last_loop_for_some_array ; $current_loop++) {
$some_array['human_readable'.($first_id_of_inserted + $current_loop)] = $some_array[$current_loop];//add new key for intial array
unset( $some_array[$current_loop] );//remove already renamed key from array
}
And here is the new array with renamed keys
echo '<pre>', print_r($some_array, true), '</pre>$some_array in '. basename(__FILE__, '.php'). '.php <br/>';
If instead of human_readable15, human_readable16, human_readable17 need something other. Then could create something like this
$arr_with_key_names[] = 'human_readable';
$arr_with_key_names[] = 'something_another';
$arr_with_key_names[] = 'and_something_else';
for ($current_loop = 0; $current_loop < $last_loop_for_some_array ; $current_loop++) {
$some_array[$arr_with_key_names[$current_loop]] = $some_array[$current_loop];//add new key for intial array
unset( $some_array[$current_loop] );//remove already renamed key from array
}
Hmm, I'm not test before, but I think this code working
function replace_array_key($data) {
$mapping = [
'old_key_1' => 'new_key_1',
'old_key_2' => 'new_key_2',
];
$data = json_encode($data);
foreach ($mapping as $needed => $replace) {
$data = str_replace('"'.$needed.'":', '"'.$replace.'":', $data);
}
return json_decode($data, true);
}
You can write simple function that applies the callback to the keys of the given array. Similar to array_map
<?php
function array_map_keys(callable $callback, array $array) {
return array_merge([], ...array_map(
function ($key, $value) use ($callback) { return [$callback($key) => $value]; },
array_keys($array),
$array
));
}
$array = ['a' => 1, 'b' => 'test', 'c' => ['x' => 1, 'y' => 2]];
$newArray = array_map_keys(function($key) { return 'new' . ucfirst($key); }, $array);
echo json_encode($array); // {"a":1,"b":"test","c":{"x":1,"y":2}}
echo json_encode($newArray); // {"newA":1,"newB":"test","newC":{"x":1,"y":2}}
Here is a gist https://gist.github.com/vardius/650367e15abfb58bcd72ca47eff096ca#file-array_map_keys-php.

Categories