Adding array to an object breaks the array - php

I have an array like this (output from print_r):
Array
(
[price] => 700.00
[room_prices] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] =>
)
[bills] => Array
(
[0] => Gas
)
)
I'm running a custom function to convert it to an object. Only the top-level should be converted, the sub-arrays should stay as arrays. The output comes out like this:
stdClass Object
(
[price] => 700.00
[room_prices] => Array
(
[0] => Array
)
[bills] => Array
(
[0] => Array
)
)
Here is my conversion function. All it does is set the value of each array member to an object:
function array_to_object( $arr )
{
$obj = new stdClass;
if ( count($arr) == 0 )
return $obj;
foreach ( $arr as $k=>$v )
$obj->$k = $v;
return $obj;
}
I can't figure this out for the life of me!

why don't you just cast the array to an object?
$myObj = (object) $myArray;

I can't reproduce (PHP 5.3):
$a = array(
"price" => 700.00,
"room_price" => array(NULL, NULL, NULL, NULL, NULL),
bills => array("Gas"),
);
function array_to_object( $arr )
{
$obj = new stdClass;
if ( count($arr) == 0 )
return $obj;
foreach ( $arr as $k=>$v )
$obj->$k = $v;
return $obj;
}
print_r(array_to_object($a));
gives
stdClass Object
(
[price] => 700
[room_price] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
[4] =>
)
[bills] => Array
(
[0] => Gas
)
)

Related

PHP Sorting Multidimensional Associative Array by Key and Value

I'm trying to sort the following data by the date in the key and the value of Name.
The aim is to a get nice date ordered array with all the Names from the inner array in alphabetical order.
Array
(
[2017-07-27] => Array
(
[0] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Orange
)
)
[4] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Apple
)
)
)
[2017-07-22] => Array
(
[6] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Apple
)
)
[7] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Orange
)
)
)
[2017-07-29] => Array
(
[9] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Orange
)
)
[11] => stdClass Object
(
[Job] => stdClass Object
(
[Name] => Plumb
)
)
)
)
I'm pretty sure I should be using array_multisort but can't quite get the desired results.
You must split the code if you want to order on object properties, use the usort function.
Where $arr is your array:
uksort($arr, 'dateCmp');
foreach($arr as &$sub){
usort($sub, 'propCmp');
}
function dateCmp($a, $b){
return (strtotime($a) < strtotime($b) ? -1 : 1);
}
function propCmp($a, $b){
return ($a->Job->Name < $b->Job->Name ? -1 : 1);
}
Please try below code,
$sorted_vals = array();
ksort($multiArrs);
foreach($multiArrs as $key => $value) { // $multiArrs = your data array
$columns = null;
foreach ($value as $index => $element) {
$columns[] = $element->Job;
}
$temp = $value;
array_multisort($columns, SORT_ASC, $temp);
$sorted_vals[$key] = $temp;
}

PHP How to restructure an array?

I have an array that I'd like to restructure. I want to group items by turn. I can figure out how to extract data from the array using foreach($arr['history'] as $obj) my issue is with populating a new array using a loop.
Currently it looks like this:
Array (
[history] => Array (
[id] => 23452435
[legend] => Array (
[0] => Array (
[player] => me
[turn] => 1
[card] => Array (
[name] => foo
)
)
[1] => Array (
[player] => me
[turn] => 1
[card] => Array (
[name] => bar
)
)
[2] => Array (
[player] => opponent
[turn] => 1
[card] => Array (
[name] => derp
)
)
[3] => Array (
[player] => opponent
[turn] => 2
[card] => Array (
[name] => hoo
)
)
)
))
I want it to look like the following, but I can't figure out how to automatically create and populate this structure. This is an array with a sub-array for each turn, containing an array for me and opponent
Array (
[0] => Array (
[me] => Array (
[0] => foo
[1] => bar
)
[opponent] = Array (
[0] => derp
)
)
[1] => Array (
[me] => Array ()
[opponent] => Array (
[0] => hoo
)
))
Thanks.
Edit:
This is what I needed. Thanks for the answers.
$result = [];
foreach ($arr['history'] as $historyItem) {
foreach ($historyItem['legend'] as $list) {
$result[$list['turn']][$list['player']][] = $list['card']['name'];
}
}
Try this:
$result = [];
foreach ($data['history']['legend'] as $list) {
$result[$list['turn']-1][$list['player']][] = $list['card']['name'];
}
Fiddle it! http://ideone.com/BtKOKJ
You can just start adding data to the new array. PHP is extremely forgiving.
$historyByTurns = array();
foreach ($arr['history'] as $historyItem) {
foreach ($historyItem['legend'] as $legendItem) {
$turn = $legendItem['turn'];
$player = $legendItem['player'];
if (!array_key_exists($turn, $historyByTurns)) {
$historyByTurns[$turn] = array();
}
if (!array_key_exists($player, $historyByTurns[$turn])) {
$historyByTurns[$turn][$player] = array();
}
foreach ($legendItem as $card) {
$historyByTurns[$turn][$player][] = $card['name'];
}
}
}
You will have to test it, as I have no way to do that ATM.

How can I merge one array with values into an array with stdClass objects?

I have two arrays and looking for the way to merge them. Standard array_merge() function don't work.
Do you know any nice solution without foreach iteration?
My first array:
Array
(
[0] => stdClass Object
(
[field_value] => Green
[count] =>
)
[1] => stdClass Object
(
[field_value] => Yellow
[count] =>
)
)
My second array:
Array
(
[0] => 2
[1] => 7
)
And as a result I would like to get:*
Array
(
[0] => stdClass Object
(
[field_value] => Green
[count] => 2
)
[1] => stdClass Object
(
[field_value] => Yellow
[count] => 7
)
)
This should work for you:
Just simply loop through both arrays with array_map() and pass the argument from array one as reference. Then you can simply assign the value to the count property.
<?php
array_map(function(&$v1, $v2){
$v1->count = $v2;
}, $arr1, $arr2);
print_r($arr1);
?>
output:
Array
(
[0] => stdClass Object
(
[field_value] => Green
[count] => 2
)
[1] => stdClass Object
(
[field_value] => Yellow
[count] => 7
)
)
[akshay#localhost tmp]$ cat test.php
<?php
$first_array = array(
(object)array("field_value"=>"green","count"=>null),
(object)array("field_value"=>"yellow","count"=>null)
);
$second_array = array(2,7);
function simple_merge($arr1, $arr2)
{
return array_map(function($a,$b){ $a->count = $b; return $a; },$arr1,$arr2);
}
print_r($first_array);
print_r($second_array);
print_r(simple_merge($first_array,$second_array));
?>
Output
[akshay#localhost tmp]$ php test.php
Array
(
[0] => stdClass Object
(
[field_value] => green
[count] =>
)
[1] => stdClass Object
(
[field_value] => yellow
[count] =>
)
)
Array
(
[0] => 2
[1] => 7
)
Array
(
[0] => stdClass Object
(
[field_value] => green
[count] => 2
)
[1] => stdClass Object
(
[field_value] => yellow
[count] => 7
)
)
it is simple
code:
$i = 0;
foreach($firstarrays as $firstarr)
{
$firstarr['count'] = $secondarray[$i];
$i++;
}
Another option:
$a1 = Array(
(object) Array('field_value' => 'Green', 'count' => null),
(object) Array('field_value' => 'Yellow', 'count' => null)
);
$a2 = Array(2, 7);
for ($i=0; $i<sizeof($a1); $i++) {
$a1[$i]->count=$a2[$i];
}

Merge 2 arrays of objects in PHP [duplicate]

This question already has answers here:
Merging and group two arrays containing objects based on one identifying column value
(4 answers)
Closed last month.
How do you merge array1 and 2?
array1
Array
(
[0] => stdClass Object
(
[name] => bob
[id] => 84569354306
[contacts] => Array
(
[0] => none
)
)
[1] => stdClass Object
(
[name] => jill
[id] => 456745742
[contacts] => Array
(
[0] => none
)
)
)
array2
Array
(
[0] => stdClass Object
(
[name] => bob
[id] => 84569354306
[pid] => 1
[lang] => eng;
[location] =>
)
[1] => stdClass Object
(
[name] => jill
[id] => 456745742
[pid] => 2
[lang] => eng;
[location] =>
)
)
Result array:
Array
(
[0] => stdClass Object
(
[name] => bob
[id] => 84569354306
[pid] => 1
[lang] => eng;
[location] =>
[contacts] => Array
(
[0] => none
)
)
[1] => stdClass Object
(
[name] => jill
[id] => 456745742
[pid] => 2
[lang] => eng;
[location] =>
[contacts] => Array
(
[0] => none
)
)
)
I've tried an array_merge() which seems to add objects next to each other in the array rather than merging the objects.
I'm pretty sure this question is similar to what I need, but I'm having difficulty with the simple foreach loop.
You can cast the two objects to array and then re-cast back to an object. The general syntax is:
$merged = (object)array_merge_recursive((array)$firstObj, (array)$secondObj);
^
| note the recursive in your case
Also, if you are using objects like that maybe you should simply stick to array. It has very little to no sense to do something like that with objects
With multiple items
If you have multiple items you simply need to wrap up my script inside a loop:
function myCustomMerge($array1, $array2) {
assert('count($array1) == count($array2)');
$result = array();
foreach($array1 as $k=>$v) {
$item = array_merge_recursive((array)$array1[$k], (array)$array2[$k]);
$result[]=$item; // use (object)$item if you need objects
}
return $result;
}
Solution without casting
If you prefer not to cast back and forth between array and object you can use get_object_vars():
$obj2props = get_object_vars($obj2);
foreach ($obj2props as $prop => $value) {
$obj1->$prop = $value;
}
return $obj;
Another way of doing it:
function merge_values(){
$list = func_get_args();
while( count( $list ) > 1 ){
$array1 = array_shift( $list );
$array2 = array_shift( $list );
$merged_array = $array1;
foreach( $array2 as $key => $value ){
$merged_array[$key] = array_merge( (array)$value, (array)$merged_array[$key] );
if( is_object( $value ) || is_object( $array1[$key] ) ){
$merged_array[$key] = (object)$merged_array[$key];
}
}
array_unshift( $list, $merged_array );
}
return current( $list );
}
$merged = merge_values( $array1, $array2 );

Merge arrays in an object

Im new to php and json. can you please suggest me on how to get the my desired output.
JSON File:
{
"1415772360":[
{"apple":"0"},
{"mango":"0"},
{"grapefruit":"0"},
{"melons":"12"},
{"peaches":"2"},
{"banana":"1"}
],
"1415772420":[
{"apple":"0"},
{"mango":"0"},
{"grapefruit":"0"},
{"melons":"7"},
{"peaches":"1"},
{"banana":"1"}
]
}
Desired Output
[
{
"minute":"1415772360",
"apple":"0",
"mango":"0",
"grapefruit":"0",
"melons":"12",
"peaches":"2",
"banana":"1”
},
{
"minute":"1415772420",
"apple:"0",
"mango":"0",
"grapefruit":"0",
"melons":"7",
"peaches":"1",
"banana":"1”
}
]
How can I do this in PHP?
I really appreciate your help. Thanks.
I would give json_decode a try. It won't get your desired output, but it will create an array from your JSON.
Documentation: http://php.net/manual/en/function.json-decode.php
My test:
$json = "{\"1415772360\":[{\"apple\":\"0\"},{\"mango\":\"0\"},{\"grapefruit\":\"0\"},
{\"melons\":\"12\"},{\"peaches\":\"2\"},{\"banana\":\"1\"}], \"1415772420\":
[{\"apple\":\"0\"},{\"mango\":\"0\"},{\"grapefruit\":\"0\"},{\"melons\":\"7\"},
{\"peaches\":\"1\"},{\"banana\":\"1\"}]}";
$new = json_decode($json);
print_r($new);
Output:
stdClass Object ( [1415772360] => Array ( [0] => stdClass Object ( [apple] => 0 )
[1] => stdClass Object ( [mango] => 0 ) [2] => stdClass Object ( [grapefruit] => 0 )
[3] => stdClass Object ( [melons] => 12 ) [4] => stdClass Object ( [peaches] => 2 )
[5] => stdClass Object ( [banana] => 1 ) ) [1415772420] => Array ( [0] => stdClass Object ( [apple] => 0 )
[1] => stdClass Object ( [mango] => 0 ) [2] => stdClass Object ( [grapefruit] => 0 )
[3] => stdClass Object ( [melons] => 7 ) [4] => stdClass Object ( [peaches] => 1 )
[5] => stdClass Object ( [banana] => 1 ) ) )
tyteen4a03 is correct that this just requires some looping to re-write the structure. This would be done as follows:
// Original JSON string
$json = '{
"1415772360":[
{"apple":"0"},
{"mango":"0"},
{"grapefruit":"0"},
{"melons":"12"},
{"peaches":"2"},
{"banana":"1"}
],
"1415772420":[
{"apple":"0"},
{"mango":"0"},
{"grapefruit":"0"},
{"melons":"7"},
{"peaches":"1"},
{"banana":"1"}
]
}';
// Convert JSON to array
$content = json_decode($json);
// Create new array container
$crate = array();
// Get minutes
foreach ($content AS $minute => $fruitbasket) {
$tmp = new stdClass;
$tmp->minutes = $minute;
// Get array of objects
foreach ($fruitbasket AS $fruits)
{
// Get object element and value
foreach ($fruits AS $key => $value)
{
// add to temporary object
$tmp->$key = $value;
}
}
// write to new array
$crate[] = $tmp;
}
print(json_encode($crate));

Categories