How to find parent array key in multidimensional array php - php

I've tried to adjust many similar solutions that I've found here on stack by none worked for me. Could someone please help me?
This multidimensional array is dynamically generated (contains 55 keys total).
There is variable $age which users enter, and $age correspondents to second array key, in this example [15]. By this key $age I have to find out parent key val $key.
In order to echo final value I need that top level array key ($key). Here is what echo would look like:
$val = $array[$key][$age]["stadij1"]["20-40"];
echo $val;
How do I target top level parent array key([0]) of key [15]?
Array
(
[0] => Array
(
[15] => Array
(
[stadij1] => Array
(
[0-20] => 0
[20-40] => 61
[40-80] => 38
[80-120] => 30
[120-xx] => 27
)
[stadij2] => Array
(
[0-20] => 0
[20-40] => 50
[40-80] => 32
[80-120] => 27
[120-xx] => 24
)...
)...
//my try
$key = array_search($age,$array); //problem is that it returns only first element
$val = $array[$key][$age]["stadij1"]["20-40"];
echo $val;

If I understood correctly, you mean something like:
function findKey($array, $age)
{
foreach ($array as $parentIndex => $parentValue) {
foreach ($row as $index => $value) {
if ($index === $age) {
return $parentIndex;
}
}
}
throw new Exception('key not found');
}

Related

How can i merge array with the same key's value

How can I merge an array like below, I want to merge tax_year by province_code
Original Array
How can I turn it into this
Target Array
Please suggest me. Thanks (Sorry I can't paste my code)
Language is PHP.
Here is the text version https:// pastebin.com/FSnUR1je
I want to merge array depend on Province Code
There is most likely a better solution than this, but this will work for you
Input
<?php
$data["0"]=["province_code"=>"1","province"=>"VT","total"=>1009,"total_amount"=>123456,"tax_year"=>"2018"];
$data["1"]=["province_code"=>"1","province"=>"VT","total"=>453,"total_amount"=>123456,"tax_year"=>"2017"];
$data["2"]=["province_code"=>"5","province"=>"SV","total"=>85,"total_amount"=>56789,"tax_year"=>"2018"];
$data["3"]=["province_code"=>"5","province"=>"SV","total"=>54,"total_amount"=>56789,"tax_year"=>"2017"];
$data2=[];
$codes=[];
foreach($data as $k=>$v){
if(isset($codes[$v['province_code']])) $k=$codes[$v['province_code']];
else $codes[$v['province_code']]=$k;
$data2[$k]['province_code']=$v['province_code'];
$data2[$k]['province']=$v['province'];
$data2[$k]['total_'.$v['tax_year']]=$v['total'];
$data2[$k]['total_amount_'.$v['tax_year']]=$v['total_amount'];
}
echo "<h2><pre>";
print_r($data2);
?>
Output
Array
(
[0] => Array
(
[province_code] => 1
[province] => VT
[total_2018] => 1009
[total_amount_2018] => 123456
[total_2017] => 453
[total_amount_2017] => 123456
)
[2] => Array
(
[province_code] => 5
[province] => SV
[total_2018] => 85
[total_amount_2018] => 56789
[total_2017] => 54
[total_amount_2017] => 56789
)
)
I would create an associative index:
$index = array();
foreach ($data as $v) {
$indexkey = $v["province_code"];
if (isset($index[$indexkey])) {
$entry = $index[$indexkey]; // key already exists, will merge
} else {
$entry = array(
"province" => $v["province"],
"province_code" => $v["pronvince_code"]
); // key does not exist, create new and then merge
}
// merge here data
$entry["total_" . $v["tax_year"]] = $v["total"];
// ...
// write entry back to the index
$index[$indexkey] = $entry;
}
Finally you can convert it back to an numeric indexed array with foreach and array_push or left it as is.

How do I get value of specific array element by secondary key?

This has to be easy but I am struggling with it. If the array below exists (named "$startersnames") and I specifically want to echo the value that has "qb" as the key, how do I do that?
I assumed $startersnames['qb'], but no luck.
$startersnames[0]['qb'] works, but I won't know that it's index 0.
Array
(
[0] => Array
(
[qb] => Tannehill
)
[1] => Array
(
[rb] => Ingram
)
[2] => Array
(
[wr] => Evans
)
[3] => Array
(
[wr] => Hopkins
)
[4] => Array
(
[wr] => Watkins
)
[5] => Array
(
[te] => Graham
)
[6] => Array
(
[pk] => Hauschka
)
[7] => Array
(
[def] => Rams
)
[8] => Array
(
[flex] => Smith
)
)
You can use array_column (from php 5.5) like this:
$qb = array_column($startersnames, 'qb');
echo $qb[0];
Demo: http://3v4l.org/QqRuK
This approach is particularly useful when you need to print all the wr names, which are more than one. You can simply iterate like this:
foreach(array_column($startersnames, 'wr') as $wr) {
echo $wr, "\n";
}
You seem to be expecting an array with text keys and value for each, but the array you have shown is an array of arrays: i.e. each numeric key has a value which is an array - the key/value pair where you are looking for the key 'qb'.
If you want to find a value at $array['qb'] then your array would look more like:
$array = [
'qb' => 'Tannehill',
'rb' => 'etc'
];
now $array['qb'] has a value.
If the array you are inspecting is a list of key/value pairs, then you have to iterate over the array members and examine each (i.e. the foreach loop shown in your first answer).
For your multi-dim array, you can loop through the outer array and test the inner array for your key.
function findKey(&$arr, $key) {
foreach($arr as $innerArr){
if(isset($innerArr[$key])) {
return $innerArr[$key];
}
}
return ""; // Not found
}
echo findKey($startersnames, "qb");
You can try foreach loop
$key = "qb";
foreach($startersnames as $innerArr){
if(isset($innerArr[$key])) {
echo $innerArr[$key];
}
}
$keyNeeded = 'qb';
$indexNeeded = null;
$valueNeeded = null;
foreach($startersnames as $index => $innerArr){
//Compare key
if(key($innerArray) === $keyNeeded){
//Get value
$valueNeeded = $innerArr[key($innerArray)];
//Store index found
$indexNeeded = $index;
//Ok, I'm found, let's go!
break;
}
}
if(!empty($indexNeeded) && !empty($valueNeeded)){
echo 'This is your value: ';
echo $startersnames[$indexNeeded]['qb'];
echo 'Or: ':
echo $valueNeeded;
}
http://php.net/manual/en/function.key.php

looping through tridimensional arrays in php

I have an array of arrays that looks like this:
Array
(
[0] => Array
(
[id] => 39
[nume] => Ardeleanu
[prenume] => Bogdan
[crm] => Array
(
)
)
[1] => Array
(
[id] => 40
[nume] => Avram
[prenume] => Corina
[crm] => Array
(
[2014-02-27] => 2
[2014-02-28] => 1
)
)
)
Here is my code :
foreach ($newOrders as $crm) {
foreach ($crm as $angajati) {
foreach ($angajati['crm'] as $val) {
echo $val;
}
}
}
I getting the Warning:
Illegal string offset 'crm'.
What am I missing ?
Does it helps ?
foreach ($newOrders as $key=>$val) {
if(array_key_exists("crm",$val) && count($val["crm"]) > 0 ){
foreach($val["crm"] as $k=>$v){
echo $k." = ".$v."<br />";
}
}
}
When we loop through a multi dimentional array its better to check if the keys are available if the corresponding values are again array and also to check if the array of values have some elements before doing loop.
So here first checking if "crm" is available and if the value i.e. again an array having some elements before doing a loop and its done by the line
if(array_key_exists("crm",$val) && count($val["crm"]) > 0 ){
This is done to avoid further notice like invalid index and invalid argument supplied in foreach if the element is missing or the data array is not present.
You're trying to loop over whole 2-nd level array, but only crm key points to array. Thus, you need to do:
foreach ($newOrders as $crm)
{
if(isset($crm['crm']))
{
foreach ($crm['crm'] as $val)
{
echo $val;
}
}
}
-if you want to get values in crm key. It may not exist, thus, I've added isset check.

How to tell if array contains another array

Well this has been a headache.
I have two arrays;
$array_1 = Array
(
[0] => Array
(
[id] => 1
[name] => 'john'
[age] => 30
)
[1] => Array
(
[id] => 2
[name] => 'Amma'
[age] => 28
)
[2] => Array
(
[id] => 3
[name] => 'Francis'
[age] => 29
)
)
And another array
array_2 = = Array
(
[0] => Array
(
[id] => 2
[name] => 'Amma'
)
)
How can I tell that the id and name of $array_2 are the same as the id and name of $array_1[1] and return $array_1[1]['age']?
Thanks
foreach($array_1 as $id=>$arr)
{
if($arr["id"]==$array_2[0]["id"] AND $arr["name"]==$array_2[0]["name"])
{
//Do your stuff here
}
}
Well you can do it in a straightforward loop. I am going to write a function that takes the FIRST element in $array_2 that matches something in $array_1 and returns the 'age':
function getField($array_1, $array_2, $field)
{
foreach ($array_2 as $a2) {
foreach ($array_1 as $a1) {
$match = true;
foreach ($a2 as $k => $v) {
if (!isset($a1[$k]) || $a1[$k] != $a2[$k]) {
$match = false;
break;
}
}
if ($match) {
return $a1[$field];
}
}
}
return null;
}
Use array_diff().
In my opinion, using array_diff() is a more generic solution than simply comparing the specific keys.
Array_diff() returns a new array that represents all entries that exists in the first array and DO NOT exist in the second array.
Since your first array contains 3 keys and the seconds array contains 2 keys, when there's 2 matches, array_diff() will return an array containing the extra key (age).
foreach ($array_1 as $arr) {
if (count(array_diff($arr, $array_2[1])) === 1) {//meaning 2 out of 3 were a match
echo $arr['age'];//prints the age
}
}
Hope this helps!
I assume you want to find the age of somebody that has a known id and name.
This will work :
foreach ($array_1 as $val){
if($val['id']==$array_2[0]['id'] && $val['name']==$array_1[0]['name']){
$age = $val['age'];
}
}
echo $age;
Try looking into this.
http://www.w3schools.com/php/func_array_diff.asp
And
comparing two arrays in php
-Best

parsing out the last number of the post

Ok so i have a post that looks kind of this
[optional_premium_1] => Array
(
[0] => 61
)
[optional_premium_2] => Array
(
[0] => 55
)
[optional_premium_3] => Array
(
[0] => 55
)
[premium_1] => Array
(
[0] => 33
)
[premium_2] => Array
(
[0] => 36 )
[premium_3] => Array
(
[0] => 88 )
[premium_4] => Array
(
[0] => 51
)
how do i get the highest number out of the that. So for example, the optional "optional_premium_" highest is 3 and the "premium_" optional the highest is 4. How do i find the highest in this $_POST
You could use array_key_exists(), perhaps something like this:
function getHighest($variableNamePrefix, array $arrayToCheck) {
$continue = true;
$highest = 0;
while($continue) {
if (!array_key_exists($variableNamePrefix . "_" . ($highest + 1) , $arrayToCheck)) {
$continue = false;
} else {
highest++;
}
}
//If 0 is returned than nothing was set for $variableNamePrefix
return $highest;
}
$highestOptionalPremium = getHighest('optional_premium', $_POST);
$highestPremium = getHighest('premium', $_POST);
I have 1 question with 2 parts before I answer, and that is why are you using embedded arrays? Your post would be much simpler if you used a standard notation like:
$_POST['form_input_name'] = 'whatever';
unless you are specifically building this post with arrays for some reason. That way you could use the array key as the variable name and the array value normally.
So given:
$arr = array(
"optional_premium_1" => "61"
"optional_premium_2" => "55"
);
you could use
$key = array_keys($arr);
//gets the keys for that array
//then loop through get raw values
foreach($key as $val){
str_replace("optional_premium_", '', $val);
}
//then loop through again to compare each one
$highest = 0;
for each($key as $val){
if ((int)$val > $highest) $highest = (int)$val;
}
that should get you the highest one, but then you have to go back and compare them to do whatever your end plan for it was.
You could also break those into 2 separate arrays and assuming they are added in order just use end() http://php.net/manual/en/function.end.php
Loop through all POST array elements, pick out elements having key names matching "name_number" pattern and save the ones having the largest number portion of the key names. Here is a PHP script which does it:
<?php // test.php 20110428_0900
// Build temporary array to simulate $_POST
$TEMP_POST = array(
"optional_premium_1" => array(61),
"optional_premium_2" => array(55),
"optional_premium_3" => array(55),
"premium_1" => array(33),
"premium_2" => array(36),
"premium_3" => array(88),
"premium_4" => array(51),
);
$names = array(); // Array of POST variable names
// loop through all POST array elements
foreach ($TEMP_POST as $k => $v) {
// Process only elements with names matching "word_number" pattern.
if (preg_match('/^(\w+)_(\d+)$/', $k, $m)) {
$name = $m[1];
$number = (int)$m[2];
if (!isset($names[$name]))
{ // Add new POST var key name to names array
$names[$name] = array(
"name" => $name,
"max_num" => $number,
"key_name" => $k,
"value" => $v,
);
} elseif ($number > $names[$name]['max_num'])
{ // New largest number in key name.
$names[$name] = array(
"name" => $name,
"max_num" => $number,
"key_name" => $k,
"value" => $v,
);
}
}
}
print_r($names);
?>
Here is the output from the script:
Array
(
[optional_premium] => Array
(
[name] => optional_premium
[max_num] => 3
[key_name] => optional_premium_3
[value] => Array
(
[0] => 55
)
)
[premium] => Array
(
[name] => premium
[max_num] => 4
[key_name] => premium_4
[value] => Array
(
[0] => 51
)
)
)
Though ineffective, you could try something like
$largest = 0;
foreach($_POST as $key => $value)
{
$len = strlen("optional_premium_");
$num = substr($key, $len);
if($num > $largest)
$largest = $num;
}
print_r($largest);
The problem being that this will only work for one set of categories. It will most likely give errors throughout the script.
Ideally, you would want to reorganize your post, make each array be something like
[optional_premium_1] => Array
(
[0] => 61
["key"] => 1
)
[optional_premium_2] => Array
(
[0] => 61
["key"] => 2
)
Then just foreach and use $array["key"] to search.

Categories