How to get data from multi dimensional array - php

( Full pastebin: https://pastebin.com/C4qV5YYv)
I'm trying to select data from a (long) multi dimensional array, but with all things I tried the page just showed as blank. I'm trying to access the data with the name instead of it's rank in the list.
{
"playerstats": {
"steamID": "76561198035223060",
"gameName": "ValveTestApp260",
"stats": [
{
"name": "total_kills",
"value": 38694
},
{
"name": "total_deaths",
"value": 33362
},
{
"name": "total_time_played",
"value": 2148546
},
{
"name": "total_planted_bombs",
"value": 770
},
{
"name": "total_defused_bombs",
"value": 271
},
{
"name": "total_wins",
"value": 12394
}, So on and so on......
I'm currently using this to get data from the array: $kills = $jsonforgame['playerstats']['stats'][0]['value'];
This works when you only need a couple of values, but it gets really tidy when I need to select values further down, like; $hit = $jsonforgame['playerstats']['stats'][47]['value'];
Is there anyway for me to select the stats with the name, like this: $hit = $jsonforgame['playerstats']['stats']['total_shots_fired']['value']; instead of the number.
Thanks in advance.

You may go for something like this:
function getStat($data, $name)
{
return array_filter($data, function($item) use ($name) {
return $item && $item['name'] === $name;
})[0]['value'];
}
$hit = getStat($jsonforgame['playerstats']['stats'], 'total_shots_fired');
But the more efficient way would be to change your stats api so it serves key-value pairs, if it is possible, ofc.

One way would be to change how you create the array as so:
{
"playerstats": {
"steamID": "76561198035223060",
"gameName": "ValveTestApp260",
"stats":
{
"total_kills": 38694,
"total_deaths": 33362,
"total_time_played": 2148546,
...
}
then simply access by $kills = $jsonforgame['playerstats']['stats']['total_kills']

In case you can't change the array, you could also try
$specs = array("total_kills", "total_deaths", "total_time_played"); // and so on
foreach ( $specs as $spec )
$$spec = $jsonforgame['playerstats']['stats'][ $spec ]['value'];
After that you can use each spec by name, for example $total_kills
If you want to use shorter variable names you can change the code like this
$specs = array(
"kills" => "total_kills",
"died" => "total_deaths",
"played" => "total_time_played"
); // and so on
foreach ( $specs as $key => $spec )
$$key = $jsonforgame['playerstats']['stats'][ $spec ]['value'];
echo $kills; // output $jsonforgame['playerstats']['stats']['total_kills']['value']
Another approach
$count = count($jsonforgame['playerstats']['stats']);
for ( $i = 0; $i < $count; $i++ ) {
$name = $jsonforgame['playerstats']['stats'][ $i ]['name'];
$value = $jsonforgame['playerstats']['stats'][ $i ]['value'];
$$name = $value;
}
and with use of the array with shorter variable names
$specs = array(
"total_kills" => "kills",
"total_deaths" => "died",
"total_time_played" => "played",
); // and so on
$count = count($jsonforgame['playerstats']['stats']);
for ( $i = 0; $i < $count; $i++ ) {
$name = $specs[ $jsonforgame['playerstats']['stats'][ $i ]['name'] ];
$value = $jsonforgame['playerstats']['stats'][ $i ]['value'];
$$name = $value;
}

Related

Problem using a for loop in a PHP nested array to it into separate arrays

Am working on a nested array in PHP (From an API) which is 4 levels deep. Am trying to use a for loop to separate/dissect the nested arrays so that they may exist as independent entities so that I may use them in the blade. e.g agency_sales , unit_sales, agents When I dd on the browser, I get agency_sales while unit_sales I only get one array..
They are stored in a variable called rsm
The array collection
"regional_sales": [
{
"id": "75875",
"agency_sales": [
{
"id": "157",
"unit_sales": [
{
"id": "777",
"agents": [
{
"agent_no": "75939",
"policies": [
"IL*********"
]
},
{
"agent_no": "75939",
"policies": [
"IL**********"
]
}
]
},
{
"id": "111",
"agents": [
{
"agent_no": "758",
"policies": [
"IL2*********"
]
},
{
"agent_no": "75939",
"policies": [
"IL20**********"
]
}
]
}
]
}
]
}
]
My For loop
for($a=0; $a < count($rsm); $a++){
$asm = $rsm[$a]['agency_sales'];
//dd($asm);
for($b = 0; $b < count($asm); $b++){
$usm = $asm[$b]['unit_sales'];
dd($usm);
for($c = 0; $c < count($usm); $c++){
$ag = $usm[$c]['agents'];
//dd($ag);
}
}
}
I think you actually want to collect all the pieces at each level separately and then push down to generate the next level arrays. That will ensure you get all the values at each level into their respective array. This should work:
$asm = array();
for($a=0; $a < count($rsm); $a++){
$asm = array_merge($asm, $rsm[$a]['agency_sales']);
}
print_r($asm);
$usm = array();
for($b = 0; $b < count($asm); $b++){
$usm = array_merge($usm, $asm[$b]['unit_sales']);
}
print_r($usm);
$ag = array();
for($c = 0; $c < count($usm); $c++){
$ag = array_merge($ag, $usm[$c]['agents']);
}
print_r($ag);
I've omitted the output as it is quite long but you can see it on the demo on 3v4l.org
You should use foreach to parse through such an array:
foreach ($data['regional_sales'] as $regional_sale) {
// Access $regional_sale['id'] or anything else
foreach ($regional_sale['agency_sales'] as $agency_sale) {
// Access $agency_sale['id'] or anything else
foreach ($agency_sale['unit_sales'] as $unit_sale) {
// Access $unit_sale['id'] or anything else
foreach ($unit_sale['agents'] as $agent) {
// Access $agent['agent_no'] or anything else
}
}
}
}
Demo: https://3v4l.org/q3dAR

Combine two arrays two one and set keys

I have been struggling with this for quite some time. I have two arrays, which I need to combine.
This is my input:
{
"array_one": {
"mrnreference": [
{
"key_0": "18DK00310020B11A84"
},
{
"key_0": "18DK00310020B11B40"
}
]
},
"array_two": {
"shipperreference": [
{
"key_0": "1861575"
},
{
"key_0": "1861549"
}
]
}
}
Now the structure is, that each item in each array follows each other. So, the result should be something like:
{
"result": [
{
"mrn" : "18DK00310020B11A84",
"shipper" : "1861575"
},
{
"mrn" : "18DK00310020B11B40",
"shipper" : "1861549"
}
]
}
However I simply cannot figure out how to do this.
I have tried to merge the two original arrays:
//Input
$array_one = $request->array_one;
$array_two = $request->array_two;
//Merge the two received arrays
$final = array_merge_recursive($array_one, $array_two);
However, this just removes array_one and array_two, but the array is still split up.
How can I combine above array, so it will have below format:
{
"mrn" : "18DK00310020B11B40",
"shipper" : "1861549"
}
You can do this with some custom code:
$array_one = $request->array_one;
$array_two = $request->array_two;
$final = array_map(function ($value, $key) use ($array_two) {
foreach ($value as $k => $v) {
return [
"mrn" => $v,
"shipper" => array_get($array_two, "shipperreference.$key.$k")
];
}
}, array_get($array_one, 'mrnreference'), array_keys(array_get($array_one, 'mrnreference')));
A very quick solution to this would be just to iterate through a for loop.
for($i = 0; $i < count($array_one); $i++){
$final[$i]["mrn"] = $array_one["mrnreference"][$i]; // Mrn key equals array one value
$final[$i]["shipping"] = $array_two["shipperreference"][$i]; // Shipping key equals array two value
}
However, this has a small caveat that it could lead to an error, if $array_one and $array_two are not the same size.
First of all array_map can be used to get the values and then in simple for loop you can combine them. Notice that the size of mrnreference and shipperreference must be the same otherwise it will pop notice
$json = '
{
"array_one": {
"mrnreference": [
{
"key_0": "18DK00310020B11A84"
},
{
"key_0": "18DK00310020B11B40"
}
]
},
"array_two": {
"shipperreference": [
{
"key_0": "1861575"
},
{
"key_0": "1861549"
}
]
}
}
';
$arr = json_decode($json, true);
$ref = array_map(function($e){return $e['key_0'];}, $arr['array_one']['mrnreference']);
$ship = array_map(function($e){return $e['key_0'];}, $arr['array_two']['shipperreference']);
$output = array();
for ($i = 0, $cnt = count($ref); $i < $cnt ; ++$i) {
$output[] = [
'mrn' => $ref[$i],
'shipper' => $ship[$i],
];
}
echo json_encode(['result' => $output]);

PHP json string: getting an associative array object

I have a json file with data like this (this is a partial view of the file to show structure):
{
"state": {
"ALABAMA": {
"ZOLD": [ "101", "102" ],
"ZNEW": [ "11", "12" ]
},
"ALASKA": {
"ZOLD": [ "5001", "5002", "5003", "5004", "5005", "5006", "5007", "5008", "5009", "5010"],
"ZNEW": [ "21", "22", "23", "24", "25", "26", "27", "28", "29", "20"]
}
}
}
What I want to do is search through it to find a value in the ZOLD field = $OLD, then return the value of the corresponding ZNEW array. I've tried going in with foreach and can get the arrays to echo out, but I'm not sure of what the value will be. Here's the code I have:
function translateZone($OLD)
{
$OLD = "5010"; //for testing purposes a constant but will be variable
$zStr = file_get_contents('getnew.json');
$zJson = json_decode($zStr,true);
foreach($zJson as $key=> $jsons)
{
foreach($jsons as $key=>$values)
{
foreach($values as $key=>$vals)
{
$counter=0;
foreach($vals as $key=>$vls)
{
$counter ++;
echo var_dump($vls);//I can see the values,but now what?
if ($vls == $OLD)
{
$zTemp = Help here -some array value of counter??
}
}
}
return $zTemp;
}
}
I've searched through a bunch of other questions but haven't found something close enough to help with the problem.
Additional information: I may or may not know the "state" string (i.e. "Alaska") but I may want to return this information as well based on the found value.
Thanks for the help.
Instead of trying to loop through ZOLD, you could use array_search (assuming that the $OLD value can only appear once in the data). This function will either return a number for the index of the value you search for or false if it cannot find it:
$index = array_search($OLD,$values['ZOLD']);
if ($index !== FALSE) {
$zTemp = $values['ZNEW'][$index];
}
This would replace your two innermost for loop (as you need the other loops to get down to this level) and iterate through each state. At this point as well, $key would be defined to your state name.
Here is another way to complete your task, this one with array_map function:
$jsonArray = json_decode($your_file_content, true);
$oldVal = "5005";
$result = [];
foreach( $jsonArray["state"] as $k => $v ) {
/**
* Here we're building an array or pairs ZOLD => ZNEW values
*/
$pairs = array_map(function($o, $n) {
return [ $o => $n ];
}, $v["ZOLD"], $v["ZNEW"]);
/**
* Filling up the result
*/
foreach( $pairs as $p )
if( isset($p[$oldVal]) )
$result[] = [
"state" => $k,
"ZNEW" => $p[$oldVal]
];
}
var_dump($result);
$result dump will contains a list or assoc arrays with "state" and "ZNEW" keys, if the corresponding ZNEW values will be found

Php array iteration with conditional indexing

I'm working on PHP array iteration. I have arrays for example as below :
1) banned 2) age
$banned = array(
"school_name"=> "abc",
"school_rating"=> "xyz",
);
$age = array(
"Peter"=> "35", // 0
"Ben"=> "16", // 1
"Joe"=> "43" // 2
"john"=> "12", // 3
);
I'm iterating over this array using foreach :
foreach($age as $index => $value) {
if ($value < '18') {
$banned['name_' . $index] = $value; // Push values below 18 to 'banned' array with index value
}
}
I want to find names which are below age 18 & push theme to 'banned' array.
This code works correct. But while pushing names to 'banned' array, I want to append new index to their names such as 'Ben_0' 'john_1'.
Current code appending index as per foreach iteration such as 'Ben_1' 'john_3'.
I want my final array to like :
$banned = array(
"school_name"=> "abc",
"school_rating"=> "xyz",
"Ben_0"=> "16",
"john_1"=> "12",
);
I want this new indexing in order to perform some API call later.
So is there any way to achieve this ?
You mean something like:
$count = 0;
foreach($age as $index => $value) {
if ($value < '18') {
$banned[$index . '_' . $count++] = $value; // Push values below 18 to 'banned' array with index value
}
}
You can do it like this:
$i = 0;
foreach($age as $index => $value)
{
if ($value < '18') {
$banned['name_' . $i] = $value; // Push values below 18 to 'banned' array with index value
$i++;
}
}
$i = 0;
foreach ($age as $name => $age)
{
$banned[$name . '_' . $i++] = $age;
}

Recursive Search Function

I have strings that come in the form of "IT/Internet/Web Development/Ajax". I parse it and make a JSON Object like
[{
"name": "IT",
"subcategories":[
{
"name": "Internet",
"subcategories" : [
{
"name": "Web Development",
"subcategories" : [
{
"name":"Ajax"
}]}]}]
I create the JSON object by doing
$input = "IT/Internet/Web Development";
$items = explode("/", $input);
$parent = null;
$firstObject = null;
while (count($items))
{
$object = new StdClass();
$item = array_shift($items);
$object->name = $item;
if (count($items) == 0) {
$object->subcategories=NULL; // I made this null in order to know that this is the last item of the string that comes in
}
if ($parent)
$parent->subcategories = array($object);
else
$firstObject = $object;
$parent = $object;
}
array_push($category_collection, $firstObject); //$category_collection is an array
}
When another string comes in, for example "IT/Internet/Browsers", I want to be able to parse the categories that were created and place "Browsers" in the correct place as a subcategory of Internet, so then my JSON object would look like
[{
"name": "IT",
"subcategories":[
{
"name": "Internet",
"subcategories" : [
{
"name": "Web Development",
"subcategories" : [
{
"name":"Ajax"
}],
{
"name":"Browsers"
}}]}]
I'm having problems writing a recursive function that will just loop the JSON Object to categorize everything in the right place. What I am doing as of right now is
$arrlength = count($category_collection); //count the size of the array
$input = "IT/Internet/Browsers";
$items = explode("/",$input);
$tempVariable = array_shift($items);
$flag = false;
for ($x = 0; $x < $arrlength; $x++) {
//Here I check if the first a category with that name already exists
if ($category_collection[$x]['name'] == $tempVariable) {
$flag = true;
//Now here is where im having problems doing the recursion to check if the subcategory2 already exists and then if subcategory 3 and so on...
}
}
If anybody could guide me on the right direction that would be greatly appreciated
Here is a full function, it should work, you can convert it to json after, if you need:
$categoriesCollection = array();
$input = "IT/Internet/Web Development";
updateCategoriesCollection(explode('/', $input), $categoriesCollection);
$input = "IT/Internet/Browsers";
updateCategoriesCollection(explode('/', $input), $categoriesCollection);
function updateCategoriesCollection(array $categoriesList, array &$categoriesCollection)
{
$name = array_shift($categoriesList);
$category = null;
foreach ($categoriesCollection as $key => $value)
{
if ($value->name == $name)
{
$category = $value;
break;
}
}
if (!$category)
{
$category = new StdClass;
$category->name = $name;
$categoriesCollection[] = $category;
}
if (!empty($categoriesList))
{
if (empty($category->subcategories)) $category->subcategories = array();
updateCategoriesCollection($categoriesList, $category->subcategories);
}
}
var_dump($categoriesCollection);
Output:
Array
(
[0] => stdClass Object
(
[name] => IT
[subcategories] => Array
(
[0] => stdClass Object
(
[name] => Internet
[subcategories] => Array
(
[0] => stdClass Object
(
[name] => Web Development
)
[1] => stdClass Object
(
[name] => Browsers
)
)
)
)
)
)
Try this please (Not tested, maybe some error to correct, i am here to help):
function boolean check_is_good($array, $input)
{
$element = array_shift($input);
for ($x = 0; $x < count($array), $x++) {
if ($array[$x]['name'] == $element){
if ((!isset($array[$x]['subcategories']) && (count($input) == 0))
return (true);
else if ((!isset($array[$x]['subcategories']) && (count($input) != 0))
return (false);
$newArray = $array[$x]['subcategories'];
return (check_is_good($newArray, $input));
}
}
return (false);
}
The function return true is all is in the correct place
You have to pass in parameter1 an array that represent your JSON ($category_collecton in your example)
You have to pass in parameter2 an array with all elements ($items in your example)

Categories