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]);
Related
I have an array and I am checking if a value exists in the array using in_array(). However, I want to check only in the ID key and not date.
$arr = ({
"ID":"10",
"date":"04\/22\/20"
},
{
"ID":"20",
"date":"05\/25\/20"
},
{
"ID":"32",
"date":"07\/13\/20"
});
So in this example, the condition should not be met since 25 exists in date, but not in ID.
if (in_array("25", $arr)) {
return true;
}
To directly do this, you need to loop over the array.
function hasId($arr, $id) {
foreach ($arr as $value) {
if ($value['ID'] == $id) return true;
}
return false;
}
If you need to do this for several IDs, it is better to convert the array to a map and use isset.
$map = array();
foreach ($arr as $value) {
$map[$value['ID']] = $value;
// or $map[$value['ID']] = $value['date'];
}
if (isset($map["25"])) {
...
}
This will also allow you to look up any value in the map cheaply by id using $map[$key].
For versions of PHP (>= 5.5.0), there is a simple way to do this
$arr = ({
"ID":"10",
"date":"04\/22\/20"
},
{
"ID":"20",
"date":"05\/25\/20"
},
{
"ID":"32",
"date":"07\/13\/20"
});
$searched_value = array_search('25', array_column($arr, 'ID'));
Here is documentation for array_column.
You can also check it by array_filter function:
$searchId = '25';
$arr = [[
"ID" => "10",
"date" => "04\/22\/20"
],
[
"ID" => "25",
"date" => "05\/25\/20"
],
[
"ID" => "32",
"date" => "07\/13\/20"
]];
$items = array_filter($arr, function ($item) use ($searchId) {
return $item['ID'] === $searchId;
});
if (count($items) > 0) {
echo 'found';
};
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
I have an Array containing sub-sets of data as following:
"options":[
{
"id":"13",
"option_name":"M",
"option_id":"1",
"label":"Size"
},
{
"id":"13",
"option_name":"L",
"option_id":"1",
"label":"Size"
},
{
"id":"13",
"option_name":"BLUE",
"option_id":"1",
"label":"Color"
},
{
"id":"13",
"option_name":"GREEN",
"option_id":"1",
"label":"Color"
}
]
I want to loop into this array and separate objects/subsets based on key label. As following:
"options":[
{
"label":"Size",
"optionsArray":[
{
"id":"11",
"option_name":"XL",
"option_id":"1",
"label":"Size",
},
{
"id":"12",
"option_name":"L",
"option_id":"1",
"label":"Size",
}
]
},
{
"label":"Color",
"optionsArray":[
{
"id":"11",
"option_name":"BLUE",
"option_id":"1",
"label":"Color",
},
{
"id":"12",
"option_name":"GREEN",
"option_id":"1",
"label":"Color",
}
]
}
]
How can i achieve this with PHP?
As this post is already full of code, stackoverflow wouldn't let me paste my current try of code, so i will try to paste simple structure as plain text.
$keys = array_keys(current($options));
$len = count($options);
foreach($keys as $key){
// Access the key first
for($i=0;$i<$len; $i++){
// access the row later
echo $array[$i][$key];
}
}
I'd do it like that:
$result = [];
foreach ($options as $option) {
if (!isset($result[$option['label']])) {
$result[$option['label']] = [
'label' => $option['label'],
'optionsArray' => []
];
}
$result[$option['label']]['optionsArray'][] = $option;
}
$result = array_values($result);
<?php
// Decode the JSON (true for using associative arrays)
$array = json_decode($json, true);
// Initialize three arrays
$colors = [];
$sizes = [];
$unknown = [];
// Loop and seperate them using a switch
foreach ($array['options'] as $o) {
if (! isset($o['label'])) {
trigger_error('label not in object', E_USER_WARNING);
}
switch($o['label']) {
case 'Size':
$sizes[] = $o;
break;
case 'Color':
$colors[] = $o;
break;
// Put all malformed objects into this array
default:
$unknown[] = $o;
}
}
// You can now easily build your new array
$output = ['options' => [
['label' => 'Size', 'optionsArray' => $sizes],
['label' => 'Color', 'optionsArray' => $colors]
]];
( 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;
}
I have example array of my data and I have to insert it into Google Charts with json. But I'd like to know how could make each Json data row with loop, so if I don't have that specific value defined I won't get an error.
$dataArray=array('item1;item2;item3;item4;item5','item2;item4;item3','item2;item3','item5;item4','item1;item4;item2');
$arrayOUT = [];
foreach ($dataArray as $a) {
$t = explode(";", $a);
foreach ($t as $y) {
if (!isset($arrayOUT[$y])) {
$arrayOUT[$y] = 0;
}
$arrayOUT[$y] += 1;
}
}
At the moment I have static json rows:
echo '{
"cols": [
{"id":"","label":"Data","pattern":"","type":"string"},
{"id":"","label":"Count","pattern":"","type":"number"}
],
"rows": [
{"c":[{"v":"item1","f":null},{"v":'.$arrayOUT['item1'].',"f":null}]},
{"c":[{"v":"item2","f":null},{"v":'.$arrayOUT['item2'].',"f":null}]},
{"c":[{"v":"item3","f":null},{"v":'.$arrayOUT['item3'].',"f":null}]},
{"c":[{"v":"item4","f":null},{"v":'.$arrayOUT['item4'].',"f":null}]},
{"c":[{"v":"item5","f":null},{"v":'.$arrayOUT['item5'].',"f":null}]}
]
}';
But I would like to have rows done with loop. So for example, if I dont have item4 in my array, it wont create this row. So it only creates rows with existing data.
echo '{
"cols": [
{"id":"","label":"Data","pattern":"","type":"string"},
{"id":"","label":"Count","pattern":"","type":"number"}
],
"rows": [
Loop this row to create dynamic rows
{"c":[{"v":"item","f":null},{"v":'.$arrayOUT['item'].',"f":null}]},
]
}';
You can create a loop over the arrayOUT object.
I edited your example:
$dataArray=array('item1;item2;item3;item4;item5','item2;item4;item3','item2;item3','item5;item4','item1;item4;item2');
$arrayOUT = [];
foreach ($dataArray as $a) {
$t = explode(";", $a);
foreach ($t as $y) {
if (!isset($arrayOUT[$y])) {
$arrayOUT[$y] = 0;
} else {
$arrayOUT[$y] += 1;
}
}
}
$rows = "";
forEach($arrayOUT as $item=>$count){
$rows = $rows."{'c':[{'v':'{$item}','f':null},{'v':'{$count}','f':null}]},";
}
echo '{
"cols": [
{"id":"","label":"Data","pattern":"","type":"string"},
{"id":"","label":"Count","pattern":"","type":"number"}
],
"rows": [
'.$rows.'
]
}';