Find a value of a key by another key's value - php

I have an array and I'm willing to find a value of a specific key in case another key's value is X.
My array has several other arrays with the following structure:
[3] => Array
(
[ŠIFRA VALUTE] => 156
[NAZIV ZEMLJE] => Kina
[OZNAKA VALUTE] => CNY
[VAŽI ZA] => 1
[SREDNJI KURS] => 16.8711
)
I'm willing to find in the main array, all the values of SREDNJI KURS only if the value of OZNAKA VALUTE is "CNY".

As far as I understood from your question:
var_dump($data);
/*
[0] => Array
(
[ŠIFRA VALUTE] => 156
[NAZIV ZEMLJE] => Kina
[OZNAKA VALUTE] => CNY
[VAŽI ZA] => 1
[SREDNJI KURS] => 16.8711
),
[1] => Array
(
[ŠIFRA VALUTE] => 156
[NAZIV ZEMLJE] => Kina
[OZNAKA VALUTE] => CNY
[VAŽI ZA] => 1
[SREDNJI KURS] => 16.8711
)*/
Just use a simple loop over the array and check where the value of that specific key is CNY.
foreach($data as $row){
if($row['OZNAKA VALUTE'] == "CNY"){
echo $row['SREDNJI KURS'];
//or save it in an array or whatever you'd like to do with it.
}
}

Related

Add element to PHP associative array in loop

I've looked but can't find an answer for my specific use case. I want to add an element to a multidimensional array while looping through it. What I have before the loop:
Array
(
[fname] => Monty
[lname] => Python
[phone] => 555 555 1212
[email] => a#b.com
[modelList] => Array
(
[0] => Array
(
[id] => 1
[modelName] => X-Wing
[remarks] =>
[htmlRemarks] =>
[category] => Vehicles
[catID] => 178
[attachedToBase] => 1
[oversized] => 0
)
)
)
In code, I'm looping through the [modelList] array and after doing some database operations what I want to do is append new elements to each model array - in the case below, the [dbID]:
Array
(
[fname] => Monty
[lname] => Python
[phone] => 555 555 1212
[email] => a#b.com
[modelList] => Array
(
[0] => Array
(
[id] => 1
[modelName] => X-Wing
[remarks] =>
[htmlRemarks] =>
[category] => Vehicles
[catID] => 178
[attachedToBase] => 1
[oversized] => 0
[dbID] => 907
)
)
)
All inputs are from a form POST, and in my php handler:
// Loop thru model entries
$modelList = json_decode($_POST["modelList"], TRUE);
foreach($modelList as $model) {
(do some work)
// Add the new element
array_push($model['dbID'], $newID);
}
But this throws an error:
PHP Warning: array_push() expects parameter 1 to be array, null given
How can I add the new element to the sub-array?
array_push
Push one or more elements onto the end of array
You can't add a key value item to an array using array_push.
Use this instead :
foreach ($modelList as $key => $model){
$modelList[$key]['dbID'] = $newID;
}
Based on your snippet with the loop are you trying to actually update the dbID?
If so, you should change the logic to:
foreach ($modelList as $key => $model) {
(do some work)
$modelList[$key]['dbID'] = $newID;
}
Why:
you cannot change contents of the array you are looping over (unless accessed by reference)
in your example code $model['dbID'] is number 907 which is not an array, hence the error message
Found it - I needed to use a reference to $model in order to update it
// Loop thru model entries
$modelList = json_decode($_POST["modelList"], TRUE);
foreach($modelList as &$model) {
(do some work)
// Add the new element
$model['dbID'] = $newID;
}
unset($model);

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;

Multidimensionnal ARRAY - 3 and 4 levels

I have this 3 and 4 multidimensionnal array ($response) which I need to "extract" some values.
Array (
[status] => 200
[response] => Array (
[api_id] => 38229dd9-8c52-11e5-80f6-22000afd0039
[meta] => Array (
[limit] => 20
[next] => /v1/Account/xxx/Call/?limit=20&offset=20
[offset] => 0
[previous] =>
[total_count] => 57 )
[objects] => Array (
[0] => Array (
[answer_time] => 2015-11-13 18:36:19+01:00
[bill_duration] => 10
[billed_duration] => 60
[call_direction] => inbound
[call_duration] => 10
[call_uuid] => dcd94e59-8775-4c81-a4b1-cd5d41d630c6
[end_time] => 2015-11-13 18:36:29+01:00
[from_number] => 3300000000
[initiation_time] => 2015-11-13 18:36:18+01:00
[parent_call_uuid] =>
[resource_uri] => /v1/Account/xxx/Call/dcd94e59-8775-4c81-a4b1-cd5d41d630c6/
[to_number] => 3300000000
[total_amount] => 0.00500
[total_rate] => 0.00500 )
[1] => Array (
[answer_time] => 2015-11-13 15:52:01+01:00 [
bill_duration] => 48
[billed_duration] => 60
[call_direction] => inbound
[call_duration] => 48
[call_uuid] => b2d3de5d-a047-4409-9f7a-825373c38f0a
[end_time] => 2015-11-13 15:52:48+01:00
[from_number] => 3300000000
[initiation_time] => 2015-11-13 15:52:00+01:00
[parent_call_uuid] =>
[resource_uri] => /v1/Account/xxx/Call/b2d3de5d-a047-4409-9f7a-825373c38f0a/
[to_number] => 3300000000
[total_amount] => 0.00500
[total_rate] => 0.00500 )
...
In the [meta] array, I need the [total_count] value and for the [object] array, I'd like to get all the values to disaply them in a row (each object is a new row).
I have tried foreach within foreach or access datas with $response[0][0][0] but nothing do.
If someone could lead me to the solution...
Thanks a lot !!
You can access the meta array through $response['response']['meta']. As you can see from your array, both response and meta are keys, and so is total_count. Hence, accessing total count is done by $response['response']['meta']['total_count'].
To then loop through all your objects, simply do
foreach ($response['response']['objects'] as $object) {
print_r($object);
}
You can also access every attribute of the object individually by using the array keys:
foreach ($response['response']['objects'] as $object) {
echo $object['answer_time'];
echo $object['bill_duration'];
echo $object['billed_duration'];
echo $object['call_direction'];
echo $object['call_duration'];
echo $object['call_uuid'];
echo $object['end_time'];
echo $object['from_number'];
echo $object['initiation_time'];
echo $object['parent_call_uuid'];
echo $object['resource_uri'];
echo $object['to_number'];
echo $object['total_amount'];
echo $object['total_rate'];
}
First, to verify, if $array is the name of your array:
$response = $array["response"];
In the [meta] array, I need the [total_count] value
echo $response["meta"]["total_count"];
and for the [object] array, I'd like to get all the values to disaply them in a row (each object is a new row).
Use a foreach() function for all the objects:
foreach($response["objects"] as $object){
print_r($object);
}
You can use the "count" function with "COUNT_RECURSIVE" flag. It counts all the items inside the 'mixed' var. It counts parent element too.
count($array['objects'],COUNT_RECURSIVE);
example
$cibo = array(
'frutta' => array('arancia', 'banana', 'mela'),
'verdura' => array('carota', 'zucchina', 'piselli')
);
echo count($cibo,COUNT_RECURSIVE); // output 8

How to display info from an array in PHP?

If my array states:
[mostPlayedGames] => Array ( [0] => stdClass Object ( [gameName] => Counter-Strike: Global Offensive [gameLink] => http://steamcommunity.com/app/730 [gameIcon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/730/69f7ebe2735c366c65c0b33dae00e12dc40edbe4.jpg [gameLogo] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/730/d0595ff02f5c79fd19b06f4d6165c3fda2372820.jpg [gameLogoSmall] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/730/d0595ff02f5c79fd19b06f4d6165c3fda2372820_thumb.jpg [hoursPlayed] => 28.0 [hoursOnRecord] => 527 [statsName] => CSGO ) [1] => stdClass Object ( [gameName] => Borderlands: The Pre-Sequel [gameLink] => http://steamcommunity.com/app/261640 [gameIcon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/261640/af5ef05eac8b1eb618e4f57354ac7b3e918ab1bd.jpg [gameLogo] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/261640/df64c72fd335a03dbcc0a19b1f81acc8db1b94ba.jpg [gameLogoSmall] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/261640/df64c72fd335a03dbcc0a19b1f81acc8db1b94ba_thumb.jpg [hoursPlayed] => 10.9 [hoursOnRecord] => 10.9 [statsName] => 261640 )
and I want to display info from the first part of the array( 0 ), how would I go about doing that if I was using code like this to display it:
echo "CS:GO Hours Played: {$user->mostPlayedGames???}, PHP_EOL;
Thank you for your time.
Your mostPlayedGames array doesn't seem like it is an stdClass of any variable named $user, so let's not over complicate it.
$mostPlayedGames = [mostPlayedGames] => Array ( [0] => stdClass Object ( [gameName]....[snippet]
Now that we have that clear:
echo "CS:GO Hours Played: ${mostPlayedGames[0]->hoursPlayed}".PHP_EOL;
You see, The first element in this is an array at position 0 so we must first move to that index position. The element at index 0 is an stdClass so then we can use the accessor method -> to grab properties of this object.

Add new pair key => value into array from another array

I have tried array_merge, to merge them based on similar keys, array_push, various [] combinations but I just can't figure this one out. I have two arrays, one looks like:
Array
(
[650] => Array
(
[Kampan] =>
[ZelvaUL] => 650
[ZelvaOV] =>
[OCS] =>
[Rezim] => Ruční
)
[651] => Array
(
[Kampan] => 3003C_DSL_upsell_TV_SU
[ZelvaUL] => 651
[ZelvaOV] =>
[OCS] => 21
[Rezim] => IN
)
[652] => Array
(
[Kampan] =>
[ZelvaUL] => 652
[ZelvaOV] =>
[OCS] => 22
[Rezim] => IN
)
And, I want to add one new key to each of 650, 651, 652... sub-arrays (I will call the key 'Barva'), and short set of values from another array (10 total) to periodically loop in each sub-array under that key, so that 1st and 11th value is the same, 2nd and 12th is the same and so on, and all to be under the same key.
It would look like:
Array
(
[650] => Array
(
[Kampan] =>
[ZelvaUL] => 650
[ZelvaOV] =>
[OCS] =>
[Rezim] => Ruční
[Barva] => 1
)
[651] => Array
(
[Kampan] => 3003C_DSL_upsell_TV_SU
[ZelvaUL] => 651
[ZelvaOV] =>
[OCS] => 21
[Rezim] => IN
[Barva] => 2
)
[652] => Array
(
[Kampan] =>
[ZelvaUL] => 652
[ZelvaOV] =>
[OCS] => 22
[Rezim] => IN
[Barva] => 3
)
...
[660] => Array
(
[Kampan] => ...
[ZelvaUL] => ...
[ZelvaOV] => ...
[OCS] => ...
[Rezim] => ...
[Barva] => 1
)
Seriously, I am out of ideas...
Thanks for any help guys.
edit:
This is the array I want to add:
$camp_barvy = array(
'background-color:#ffffff;color:#111111;',
'background-color:#ffcc02;color:#111111;',
'background-color:#ff7700;color:#ffffff;',
'background-color:#ff2323;color:#ffffff;',
'background-color:#ff00aa;color:#ffffff;',
'background-color:#aa44ff;color:#ffffff;',
'background-color:#1188ff;color:#ffffff;',
'background-color:#11ddff;color:#111111;',
'background-color:#00dd77;color:#111111;',
'background-color:#119911;color:#ffffff;'
);
I wanna do some large and extensive conditioned formatting and both javascript and php if statement make the loading too slow, so I figured I will make the format part of the array I already look in for the values based on which I choose the desired format.
Really, its the best choice :)
What you want to do is iterate over each value in your "input" array and insert in it a new value taken from your "data" array (those 10 values you mention). When your data array is exhausted, you want to loop back to its start and continue inserting values in the "input" array elements.
So you want something like:
foreach ($input as &$row) {
$row['Brava'] = $next_item_from_data_array;
}
which leaves just the problem of how to easily iterate and loop over the data array.
A convenient and modern way of doing this is by using the built-in SPL iterators: an ArrayIterator for your data array and an InfiniteIterator around that so that you loop back to the start automatically as required. This way you also don't have to assume anything about your data array (such as if it is numerically indexed or not).
For example:
$dataIterator = new InfiniteIterator(new ArrayIterator($data));
$dataIterator->rewind();
foreach ($input as &$row) {
$row['Brava'] = $dataIterator->current();
$dataIterator->next();
}
// After iterating by reference (&$row) it is always a good idea to unset
// the reference so that you don't reuse it later on by mistake -- although
// this is not required and the program will work correctly without it.
unset($row);
See it in action.

Categories