associative array mapping - php

Dunno if it is the right title or not, but i'm struggling to do the following thing:
say I have this array
Array
(
[0] => Array
(
[id_ptp] => 1
[denumire_ptp] => Hrană uscată
)
[1] => Array
(
[id_ptp] => 2
[denumire_ptp] => Hrană umedă
)
[2] => Array
(
[id_ptp] => 3
[denumire_ptp] => Hrană vie
)
)
how can I make it to become like this:
[
'1' => 'Hrană uscată',
'2' => 'Hrană umedă',
'3' => 'Hrană vie',
]
Better question, is there a function that does that? Because I was not able to find it.

array_column it is. Here is the one liner.
$result = array_column($your_array, 'denumire_ptp', 'id_ptp');
result : https://3v4l.org/qU0EU

Related

Printing parts of an array in PHP

please excuse if this question is already answered elsewhere, but I just don't know what to search for, since I usually don't work with php.
I've got the following array:
(
[0] => Array
(
[login] => name23
[id] => 12356
)
[1] => Array
(
[login] => name12
[id] => 12345
)
[2] => Array
(
[login] => name34
[id] => 12367
)
)
And I'd like to only print the login-names, so in this example name23, name12, name34 (But I never know how many there are).
I've tried several approaches with foreach, which didn't work.
What is working, but only for one username is this:
echo $contributors[0]['login'];
How can I display all login-names?
Any help would be much appreciated.
Thanks in advance!
array_map is a universal function for tasks like this, in your case, this code would work:
$array = [['login' => "name23", 'id' => 12356], ['login' => "name12", 'id' => 12345], ['login' => "name34", 'id' => 12367]];
print_r(array_map(function($data) { return $data['login']; }, $array));
Manual: https://www.php.net/array-map
But for your specific task, array_column is simpler, as recommended by Aghilan B.
There is also array_walk function that can be used like this:
$array = [['login' => "name23", 'id' => 12356], ['login' => "name12", 'id' => 12345], ['login' => "name34", 'id' => 12367]];
array_walk($array, function($data) { print $data['login'] . "\n"; });
That can be useful if you want to do more with the logins than just printing it, it would not need to iterate twice.
You can use array_column() Function
$array = [['login' => "name23", 'id' => 12356], ['login' => "name12", 'id' => 12345], ['login' => "name34", 'id' => 12367]];
$login_array = array_column($array, 'login');
print_r($login_array);
Output
Array
(
[0] => "name23"
[1] => "name12"
[2] => "name34"
)
Use implode(', ', $login_array); to print as a string with commas

PHP search JSON without looping

I have a large JSON array which is the result of querying the API of an Icinga2 monitoring system.
I have used json_decode like this in my code to decode it:
$response = json_decode($array, true);
and I can see the output looks like this:
Array
(
[results] => Array
(
[0] => Array
(
[attrs] => Array
(
[__name] => HOSTNAME0
[acknowledgement] => 0
[acknowledgement_expiry] => 0
...
...
[state] => 0
[state_type] => 1
[meta] => Array
(
)
[name] => HOSTNAME0
[type] => Host
)
[1] => Array
(
[attrs] => Array
(
[__name] => HOSTNAME1
[acknowledgement] => 0
[acknowledgement_expiry] => 0
...
...
[state] => 0
[state_type] => 1
[meta] => Array
(
)
[name] => HOSTNAME1
[type] => Host
)
There are 400 Records in total and it's quite a complex structure but the only bits I am really interested in are the name and state fields.
Basically my script has a list of 150 hostnames from another source and what I want to do is for each hostname, search for it in the array and return the value of the state field for that host.
So far I've been struggling to do this without looping through the entire array for each of the 150 hostnames. There must be a more efficient way to do a lookup in the array based on a hostname and return a single value but I can't figure it out.
Given, the name field has no logical sorting inside the json result, there is no way to look at least once at each element. If they are sorted alphabetical, you could use a simple binary search, which would give you the result in O(log(n)).
The other thing is, if you have to search for multiple names, you could put them inside an name assiciated array. This way, you only have an initial overhead of O(n) building the list and each following search would return you the state on O(1).
// building the array
$states = [];
foreach ($items as $item) {
$states[$item['name']] = $item['state'];
}
looking for HOSTNAME1
$state = $states['HOSTNAME1'];
I'm hoping that I've got the source data array in the correct layout as the format was a bit confusing from the original question. But the main idea is to use array_column to extract the "attrs" and key the result by the "name" element of this array.
$response = Array(
"results" => Array(
0 => Array(
"attrs" => Array(
"__name" => "HOSTNAME0",
"acknowledgement" => 0,
"acknowledgement_expiry" => 0,
"state" => 0,
"state_type" => 1
),
"name" => "HOSTNAME0",
"type" => "Host"
),
1 => Array(
"attrs" => Array(
"__name" => "HOSTNAME1",
"acknowledgement" => 0,
"acknowledgement_expiry" => 0,
"state" => 2,
"state_type" => 1
),
"name" => "HOSTNAME1",
"type" => "Host1"
)
)
);
$extract = array_column($response["results"], "attrs", "name");
print_r($extract);
With the sample data, this gives...
Array
(
[HOSTNAME0] => Array
(
[__name] => HOSTNAME0
[acknowledgement] => 0
[acknowledgement_expiry] => 0
[state] => 0
[state_type] => 1
)
[HOSTNAME1] => Array
(
[__name] => HOSTNAME1
[acknowledgement] => 0
[acknowledgement_expiry] => 0
[state] => 2
[state_type] => 1
)
)
So to find any server by name, you'd use
echo "HOSTNAME1=".$extract["HOSTNAME1"]["state"].PHP_EOL;
If you only wanted the state field (as you asked for) and wanted to simplify the array, you can then use...
array_walk($extract, function(&$data) {$data=$data["state"];});
print_r($extract);
The array_walk() goes through the array and just copies the state field to be the entry, so the result of this is...
Array
(
[HOSTNAME0] => 0
[HOSTNAME1] => 2
)
So now you just do...
echo "HOSTNAME1=".$extract["HOSTNAME1"].PHP_EOL;

PHP - How to properly merge 2 arrays multi level in this example?

I have the follow array:
$arrIni["ENV"]="US";
$arrIni["sap_db_server"] = "192.xxx.x.xx";
$arrIni["local_db_server"] = "localhost";
$arrIni["local_db_username"] = "root";
//Default settings
$arrIni["arrEnvSettings"]["UserTypeID"]=4;
$arrIni["arrEnvSettings"]["LocalizationID"]=1;
$arrIni["arrEnvSettings"]["LangLabels"] = array();
$arrIni["arrEnvSettings"]["pages"]["st1"]="st1.php";
$arrIni["arrEnvSettings"]["pages"]["st2"]="st2.php";
$arrIni["arrEnvSettings"]["pages"]["st3"]="st3.php";
And I want to merge with this one:
$setParam["arrEnvSettings"]["pages"]["st3"]="st3_V2.php";
This is what I am doing:
echo "<pre>";
print_r(array_merge($arrIni,$setParam));
echo "</pre>";
And this is what I am getting:
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[pages] => Array
(
[st3] => st3_V2.php
)
)
)
In the php doc about merge, this is the comment " ...If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. ..."
So in this way, I suppose to get this output instead of the last one:
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[UserTypeID] => 4
[LocalizationID] => 1
[LangLabels] => Array
(
)
[pages] => Array
(
[st1] => st1.php
[st2] => st2.php
[st3] => st3_V2.php
)
)
)
I do not understand why $setParam["arrEnvSettings"]["pages"]["st3"] is overriding the entire $arrIni["arrEnvSettings"].
Note:
If I use array_merge_recursive($arrIni,$setParam)) I will have the follow result but it is not what I want.
Array
(
[ENV] => US
[sap_db_server] => 192.xxx.x.xx
[local_db_server] => localhost
[local_db_username] => root
[arrEnvSettings] => Array
(
[UserTypeID] => 4
[LocalizationID] => 1
[LangLabels] => Array
(
)
[pages] => Array
(
[st1] => st1.php
[st2] => st2.php
[st3] => Array
(
[0] => st3.php
[1] => st3_V2.php
)
)
)
)
Is there a way to do this without iterate over the array? Only using merging? What am I doing wrong?
This should do the trick:
array_replace_recursive($arrIni,$setParam);
If you want to merge a given value, use this:
$arrIni["arrEnvSettings"]["pages"]["st3"] = $setParam["arrEnvSettings"]["pages"]["st3"];
But the way you're doing it is merging two arrays, not simply setting the value within an array. There's a gigantic difference between those two methods.
Otherwise, yes you will need to iteratively merge the arrays.
what you need is array_replace_recursive
print_r(array_replace_recursive($arrIni,$setParam));
didnt see the submitted answer..Felippe Duarte has given it already.....

Put a key of end of an array in php

I have this array:
Array
(
[0] => Array
(
[date] => 2016-03-08
[value] => Array
(
[key_1] => Array
(
[test_1] => 1
[test_2] => 10
[test_3] => 1000
[test_4] => 200
)
[key_2] => Array
(
[test_1] => 1
[test_2] => 15
[test_3] => 1500
[test_4] => 100
)
)
)
Now I have another array :
Array
(
[key_3] => Array
(
[test_1] =>
[test_2] =>
[test_3] =>
[test_4] => 1
)
)
I want to add this last array in the first array.
I try like this : array_push($ymlParsedData[]['value'], $a_big_gift); but not work. Can you help me please ?
You can't use $ymlParsedData[] for accessing specific element, it is a shorthand for pushing data to array.
You can use either
// NB! array_push() just adds the values, key 'key_3' is removed
array_push($ymlParsedData[0]['value'], $a_big_gift);
or
// will keep key 'key_3'
$ymlParsedData[0]['value']['key_3'] = $a_big_gift['key_3'];
or
// use array_merge() instead
$ymlParsedData[0]['value'] = array_merge($ymlParsedData[0]['value'], $a_big_gift);
A complicated answer, but this might solve your issue:
$key_name = array_keys($a_big_gift)[0];
$ymlParsedData[0]['value'][$key_name] = $a_big_gift[$key_name];
echo '<pre>'; print_r($ymlParsedData); exit;
Note: For making it dynamic and for more than one value of $a_big_gift, you need to loop it and achieve your result.
Try this
array_push($ymlParsedData[0]['value'], $a_big_gift['key_3']);

Rewrite array keys by matching it to first child key, possible in php?

I'm wondering if there is an easy way to match array key to logo_id?
If I cannot find a way to do this, I will need to use array search which can become quite slow with an array of 200 items. Right?
p.s. this is result returned by mysqli fetch result call. Maybe this can be modified to provide array which I need?
Array
(
[0] => Array
(
[logo_id] => 1
[logo_name] => beeline
[logo_level] => 1
[logo_image_path] => logos/1.png
[logo_value] => 2
[logo_hints] =>
)
[1] => Array
(
[logo_id] => 2
[logo_name] => geocell
[logo_level] => 1
[logo_image_path] => logos/2.png
[logo_value] => 4
[logo_hints] =>
)
[2] => Array
(
[logo_id] => 3
[logo_name] => google
[logo_level] => 1
[logo_image_path] => logos/3.png
[logo_value] => 5
[logo_hints] =>
)
[3] => Array
(
[logo_id] => 5
[logo_name] => coca cola
[logo_level] => 1
[logo_image_path] => logos/5.png
[logo_value] => 2
[logo_hints] =>
)
)
Did I explain it good? phh, sorry for bad wording.
this is result returned by mysqli fetch result call. Maybe this can be modified to provide array which I need?
Yes. I assume you mean mysqli_result::fetch_all. Use mysqli_result::fetch_row in a loop instead and construct your array manually with whatever keys you like to.

Categories