php transform array into multidim array - php

So I'm working on a website with Doctrine as ORM and I get the following array back as a result:
Array (
[0] => Array (
[c_cat_id] => 1
[c_title] => Programas e projetos
[p_menu] => PBA BR 163
[p_page_id] => 1
)
[1] => Array (
[c_cat_id] => 1
[c_title] => Programas e projetos
[p_menu] => Outros projetos
[p_page_id] => 3
)
)
Is it possible to transform this array (in PHP) to something like this:
Array (
[0] => Array (
[c_cat_id] => 1
[c_title] => Programas e projetos
[pages] => Array (
[0] => Array (
[p_page_id] => 1
[p_menu] => PBA BR 163
)
[1] => Array (
[p_page_id] => 3
[p_menu] => Outros projetos
)
)
)
)
Thanks for your help, always eager to learn new ways of doing things and that's why I love StackOverflow ;)

Tested and working:
Code:
$original = array(
array(
"c_cat_id" => "1",
"c_title" => "Programas e projetos",
"p_menu" => "PBA BR 163",
"p_page_id" => "1"),
array(
"c_cat_id" => "1",
"c_title" => "Programas e projetos",
"p_menu" => "Outros projetos",
"p_page_id" => "3"),
array(
"c_cat_id" => "2",
"c_title" => "Another Cat",
"p_menu" => "Outros projetos",
"p_page_id" => "4"),
);
$result = array();
foreach ($original as $row) {
$cat = $row['c_cat_id'];
if (!isset($result[$cat])) {
$result[$row['c_cat_id']] = array(
'c_cat_id'=>$row['c_cat_id'],
'c_title'=>$row['c_title'],
'pages'=>array(),
);
}
unset($row['c_cat_id'],$row['c_title']);
$result[$cat]['pages'][] = $row;
}
var_dump($result);
Result:
array(2) {
[1]=>
array(3) {
["c_cat_id"]=>
string(1) "1"
["c_title"]=>
string(20) "Programas e projetos"
["pages"]=>
array(2) {
[0]=>
array(2) {
["p_menu"]=>
string(10) "PBA BR 163"
["p_page_id"]=>
string(1) "1"
}
[1]=>
array(2) {
["p_menu"]=>
string(15) "Outros projetos"
["p_page_id"]=>
string(1) "3"
}
}
}
[2]=>
array(3) {
["c_cat_id"]=>
string(1) "2"
["c_title"]=>
string(11) "Another Cat"
["pages"]=>
array(1) {
[0]=>
array(2) {
["p_menu"]=>
string(15) "Outros projetos"
["p_page_id"]=>
string(1) "4"
}
}
}
}

It looks like you want to take an Array of pages and turn it into an array of categories with each containing an array of pages.
$inputArray = array(...); // whatever you have originally
$catArray = array();
foreach($inputArray as $page) {
addToCatArray($page);
}
function addToCatArray($page) {
$found = false;
foreach($catArray as $cat) {
if ($cat['c_cat_id'] == $page['c_cat_id'] {
$newPage = array('p_page_id' => $page['p_page_id'], 'p_menu' => $page['p_menu']);
$cat['pages'][] = $newPage;
$found = true;
break;
}
}
if (!$found) { // create a new category
$newCat = array('c_cat_id' => $page['c_cat_id'], 'c_title' => $page['c_title']);
$newPage = array('p_page_id' => $page['p_page_id'], 'p_menu' => $page['p_menu']);
$newCat['pages'] = array($newPage);
$catArray[] = $newCat;
}
}

Related

PHP getting sum of values group by key in array [duplicate]

This question already has answers here:
How to GROUP BY and SUM PHP Array? [duplicate]
(2 answers)
Closed 9 months ago.
i have bellow array
Array
(
[0] => stdClass Object
(
[gross_weight] => 20.500
[net_weight] => 10.500
[product_id] => 1120280
)
[1] => stdClass Object
(
[gross_weight] => 20.500
[net_weight] => 10.500
[product_id] => 1120281
)
[2] => stdClass Object
(
[gross_weight] => 20.500
[net_weight] => 10.500
[product_id] => 1120281
)
[3] => stdClass Object
(
[gross_weight] => 20.500
[net_weight] => 10.500
[product_id] => 1120280
)
)
i want loop through this records and get the sum of gross_weight and net_weight group by product_id
i tried bellow code but not able to continue from here get the out put
foreach ($my_array as $my_array_data) {
$mark_product_id = $my_array_data->product_id;
$gross_weight_mt = $mrkgdata->gross_weight_mt;
$net_weight_mt = $mrkgdata->net_weight_mt;
}
my desired out put is to get the gross_weight and net_weight for each product id in new array.
Array
(
[0] => stdClass Object
(
[gross_weight] => 41.000
[net_weight] => 21.000
[product_id] => 1120280
)
[1] => stdClass Object
(
[gross_weight] => 41.000
[net_weight] => 21.000
[product_id] => 1120281
)
)
public function getGroupByData($data) {
$groups = array();
foreach ($data as $item) {
$key = $item['product_id'];
if (!array_key_exists($key, $groups)) {
$groups[$key] = array(
'id' => $item['product_id'],
'gross_weight' => $item['gross_weight'],
'net_weight' => $item['net_weight'],
);
} else {
$groups[$key]['gross_weight'] = $groups[$key]['gross_weight'] + $item['gross_weight'];
$groups[$key]['net_weight'] = $groups[$key]['net_weight'] + $item['net_weight'];
}
}
return $groups;
}
use php array as dictionary, and then just add the gross_weight and net_weight with += operator
$json = '
[
{
"gross_weight" : 20500,
"net_weight" : 10500,
"product_id" : 1120280
},
{
"gross_weight" : 20500,
"net_weight" : 10500,
"product_id" : 1120281
},
{
"gross_weight" : 20500,
"net_weight" : 10500,
"product_id" : 1120281
},
{
"gross_weight" : 20500,
"net_weight" : 10500,
"product_id" : 1120280
}
]
';
$x = json_decode($json);
var_dump($x);
$total = array();
foreach($x as $key => $val) {
if(empty($total[$val->product_id])) $total[$val->product_id] = array( "net_weight"=>0, "gross_weight"=>0, "product_id"=>$val->product_id );
$total[$val->product_id]["net_weight"] += $val->net_weight;
$total[$val->product_id]["gross_weight"] += $val->gross_weight;
}
$result = array_values($total);
var_dump($result);
result:
array(4) {
[0]=>
object(stdClass)#8 (3) {
["gross_weight"]=>
int(20500)
["net_weight"]=>
int(10500)
["product_id"]=>
int(1120280)
}
[1]=>
object(stdClass)#7 (3) {
["gross_weight"]=>
int(20500)
["net_weight"]=>
int(10500)
["product_id"]=>
int(1120281)
}
[2]=>
object(stdClass)#6 (3) {
["gross_weight"]=>
int(20500)
["net_weight"]=>
int(10500)
["product_id"]=>
int(1120281)
}
[3]=>
object(stdClass)#5 (3) {
["gross_weight"]=>
int(20500)
["net_weight"]=>
int(10500)
["product_id"]=>
int(1120280)
}
}
array(2) {
[0]=>
array(3) {
["net_weight"]=>
int(21000)
["gross_weight"]=>
int(41000)
["product_id"]=>
int(1120280)
}
[1]=>
array(3) {
["net_weight"]=>
int(21000)
["gross_weight"]=>
int(41000)
["product_id"]=>
int(1120281)
}
}

How could I get each value of an array?

I have an array like this :
array(3) {
["data"]=> array(1) {
["mesq_G3SC"]=> array(1) {
["data"]=> object(stdClass)#30 (19) {
["cart_id"]=> string(13) "mesq_G3SC"
["qty"]=> string(4) "2.00"
["price"]=> string(5) "11400"
["product_id"]=> string(1) "6"
["member_id"]=> string(1) "5"
["session_id"]=> string(32) "4dedde2a2eb12b25e940b7051a5f65a1"
["date_added"]=> string(19) "2016-09-28 10:39:06"
["date_modified"]=> string(19) "2016-09-28 10:39:06"
["status"]=> string(7) "pending"
["category_id"]=> string(1) "2"
["location"]=> string(9) "England"
["square"]=> string(3) "300"
["stock"]=> string(3) "260"
["folder_name"]=> string(23) "assets/uploads/products"
["photo1"]=> string(11) "photo1.jpg"
["photo2"]=> string(11) "pc.jpg"
["category_name"]=> string(6) "PC"
["is_published"]=> string(1) "1"
["modified_by"]=> NULL
}
}
}
["total_item"]=> int(1)
["total_price"]=> string(8) "11400.00"
}
I would to get each value of that array with foreach but I got error
Trying to get property of non-object...
I developed this with Codeigniter and this is my foreach:
foreach ($data as $row) {
echo $row->product_id;
}
This is what I get if I do print_r($row) :
Array ( [mesq_G3SC] => Array ( [data] => stdClass Object ( [cart_id] => mesq_G3SC [qty] => 2.00 [price] => 11400 [product_id] => 6 [member_id] => 5 [session_id] => 4dedde2a2eb12b25e940b7051a5f65a1 [date_added] => 2016-09-28 10:39:06 [date_modified] => 2016-09-28 10:39:06 [status] => pending [category_id] => 2 [lokasi_lahan] => England [square] => 300 [stock] => 260 [folder_name] => assets/uploads/products [photo1] => photo1.jpg [photo2] => photo2.jpg [category_name] => PC [is_published] => 1 [modified_by] => ) ) ) 1 11400.00
Anyone knows how to get each value of that array?
I re-created your multidimensional array, if you want to get the deepest values, here it is:
$deepest_values = array();
foreach($arr_ as $first_level_key => $first_level_value) {
if(is_array($first_level_value)) {
foreach($first_level_value as $second_level_key => $second_level_value) {
if(is_array($second_level_value)) {
foreach($second_level_value as $third_level_key => $third_level_value) {
if(is_array($third_level_value)) {
foreach($third_level_value as $fourth_level_key => $fourth_level_value) {
$deepest_values[$fourth_level_key] = $fourth_level_value;
}
}
}
}
}
}
}
echo '<pre>';
print_r($deepest_values);
echo '</pre>';
if mesq_G3SC is the key you want to iterate over - i suggest you do the following
$obj = new stdClass();
$obj->cart_id = "mesq_G3SC";
$obj->qty = "2.00";
$obj->price = "11400";
$obj->product_id = "6";
$obj->member_id = "5";
$obj->session_id = "4dedde2a2eb12b25e940b7051a5f65a1";
$obj->date_added = "2016-09-28 10:39:06";
$obj->date_modified = "2016-09-28 10:39:06";
$obj->status = "pending";
$obj->category_id = "2";
$obj->location = "England";
$obj->square = "300";
$obj->stock = "260";
$obj->folder_name = "assets/uploads/products";
$obj->photo1 = "photo1.jpg";
$obj->photo2 = "pc.jpg";
$obj->category_name = "PC";
$obj->is_published = "1";
$obj->modified_by = NULL;
$data = array(
"mesq_G3SC"=> array(
"data"=> $obj
),
"total_item" => 1,
"total_price" => "11400.00"
);
foreach($data['mesq_G3SC'] AS $key => $obj)
{
echo $key;
print_r($obj);
}
Update: i simulated your array - and it works like a charm - there is something wrong with the keys - instead of var_dump try to print_r your data array and show us the output pls

Replacing inner keys from multidimensional array in PHP

Having the following array:
array(4) {
[0]=>
array(2) {
[0]=>
string(3) "233"
[1]=>
string(37) "some data"
}
[1]=>
array(2) {
[0]=>
string(3) "233"
[1]=>
string(68) "some other data"
}
[2]=>
array(2) {
[0]=>
string(3) "144"
[1]=>
string(38) "some other data"
}
[3]=>
array(2) {
[0]=>
string(3) "233"
[1]=>
string(42) "some other data"
}
}
I want to replace the values 233 and 144 (the key 0 from the inner array) by some random HEX color. The ones with the same keys (233) for example, has to have the same HEX color (FFF000 for example in the desired solution above).
This is the function I use to generate random HEX colors:
function randHEXcolor() {
return sprintf('%06X', mt_rand(0, 0xFFFFFF));
}
My desired output should be:
array(4) {
[0]=>
array(2) {
[0]=>
string(6) "FFF000"
[1]=>
string(37) "some data"
}
[1]=>
array(2) {
[0]=>
string(6) "FFF000"
[1]=>
string(68) "some other data"
}
[2]=>
array(2) {
[0]=>
string(6) "111333"
[1]=>
string(38) "some other data"
}
[3]=>
array(2) {
[0]=>
string(6) "FFF000"
[1]=>
string(42) "some other data"
}
}
How can I archieve this?
Thanks in advance.
foreach ($array as &$item) {
if (!isset($temp[$item[0]]) {
$temp[$item[0]] = randHEXcolor();
}
$item[0] = $temp[$item[0]];
}
If you want all values to be translated to the same random color, you'll have to save those colors:
$colors_translation = array();
foreach ($array as &$item) {
$color = $item[ 0 ];
$translate = $colors_translation[ $color ];
if (empty($translate)) {
$colors_translations[ $color ] = $translate = randHEXcolor();
}
$item[ 0 ] = $translate;
}
The solution using in_array and isset functions:
$keys = [];
foreach ($arr as &$v) { // $arr is your initial array
if (in_array($v[0], ['233', '144'])) {
if (!isset($keys[$v[0]])) $keys[$v[0]] = sprintf('%06X', mt_rand(0, 0xFFFFFF));
$v[0] = $keys[$v[0]];
}
}
print_r($arr);
The output:
Array
(
[0] => Array
(
[0] => 65A4BB
[1] => some data
)
[1] => Array
(
[0] => 65A4BB
[1] => some data
)
[2] => Array
(
[0] => DDB588
[1] => some data
)
[3] => Array
(
[0] => 65A4BB
[1] => some data
)
)
This code will create a color map as the array is traversed. Pre-populate $colorMap if you want pre-defined color translations.
<?php
$array = array(
0 => array(
0 => "233",
1 => "some data"
),
1 => array(
0 => "233",
1 => "some data"
),
2 => array(
0 => "144",
1 => "some data"
),
3 => array(
0 => "233",
1 => "some data"
),
);
$colorMap = array();
foreach ($array as &$inner) {
if (!array_key_exists($inner[0],$colorMap)) {
$newColor = randHEXcolor();
$colorMap[$inner[0]] = $newColor;
$inner[0] = $newColor;
} else {
$inner[0] = $colorMap[$inner[0]];
}
}
function randHEXcolor() {
return sprintf('%06X', mt_rand(0, 0xFFFFFF));
}
print_r($array);
print_r($colorMap);
Array
(
[0] => Array
(
[0] => F1519A
[1] => some data
)
[1] => Array
(
[0] => F1519A
[1] => some data
)
[2] => Array
(
[0] => 2F7D00
[1] => some data
)
[3] => Array
(
[0] => F1519A
[1] => some data
)
)
Array
(
[233] => F1519A
[144] => 2F7D00
)
Try:
<?php
$array = array(
0 => array(
0 => "233",
1 => "some data"
),
1 => array(
0 => "233",
1 => "some data"
),
2 => array(
0 => "144",
1 => "some data"
),
3 => array(
0 => "233",
1 => "some data"
),
);
function randHEXcolor() {
return sprintf('%06X', mt_rand(0, 0xFFFFFF));
}
$firstHex = randHEXcolor();
$secondHex = randHEXcolor();
foreach($array as $arrayIndex => &$arrayValue){
if($arrayValue[0] == "144"){
$arrayValue[0] = $firstHex;
}
if($arrayValue[0] == "233"){
$arrayValue[0] = $secondHex;
}
}
output:
array(4) {
[0]=>
array(2) {
[0]=>
string(6) "AB8248"
[1]=>
string(9) "some data"
}
[1]=>
array(2) {
[0]=>
string(6) "AB8248"
[1]=>
string(9) "some data"
}
[2]=>
array(2) {
[0]=>
string(6) "22AF8B"
[1]=>
string(9) "some data"
}
[3]=>
&array(2) {
[0]=>
string(6) "AB8248"
[1]=>
string(9) "some data"
}
}

Add xml child to array php

I'm trying to add each <outfit>Subnodes</outfit> subnodes to an array using php.
My actual code:
public static function get_outfits($username) {
$files = self::user_files($username);
$data = self::request($files['outfits']);
$data = #simplexml_load_string($data);
if ( $data && count(#$data->xpath('//outfits/outfit')) > 0 ) {
foreach(#$data->xpath('//outfits/outfit/*') as $items) {
$response['outfits']['items'][] = array(
"url" => (string)$items['url'],
"c" => (string)$items['c'],
"c2" => (string)$items['c2'],
"displayName" => (string)$items['displayName'],
"z" => (string)$items['z'],
"id" => (string)$items['id'],
"isUgc" => (string)$items['isUgc']
);
}
}
return (isset($response) ? $response : false);
}
The xml document looks like the following: http://outfits.zwinky.com/users/220/287/_perverted/outfits.xml
Sadly the code is saving every existing child into one array. But I'm trying to create an array index for each <outfit></outfit> node which should contain the child elements.
For example:
Array[0] = Everything between the first <outfit><outfit>
Array[1] = Everything between the second <outfit><outfit>
Does anyone have an idea, how to create this?
You need two loops, one for the outfit elements and one for the inner item elements. On the other side, you don't need the condition, because iterating an empty array/node list works fine.
$outfits = new SimpleXmlElement($xml);
$result = [];
foreach ($outfits->xpath('outfit') as $outfit) {
$items = [];
foreach ($outfit->xpath('*') as $item) {
$items[$item->getName()] = [
"url" => (string)$item['url'],
"c" => (string)$item['c'],
"c2" => (string)$item['c2'],
"displayName" => (string)$item['displayName'],
"z" => (string)$item['z'],
"id" => (string)$item['id'],
"isUgc" => (string)$item['isUgc']
];
}
$result[] = [
'name' => (string)$outfit['name'],
'items' => $items
];
}
var_dump($result);
Output:
array(14) {
[0]=>
array(2) {
["name"]=>
string(6) "babe13"
["items"]=>
array(14) {
["head"]=>
array(7) {
["url"]=>
string(51) "http://.../assets/babe/heads/01/head1"
["c"]=>
string(8) "0xF4C4A4"
["c2"]=>
string(8) "0xffffff"
["displayName"]=>
string(0) ""
["z"]=>
string(5) "33000"
["id"]=>
string(0) ""
["isUgc"]=>
string(0) ""
}
["face"]=>
array(7) {
["url"]=>
string(50) "http://.../assets/babe/faces/01/grl1"
["c"]=>
string(3) "0x0"
["c2"]=>
string(8) "0xFF0000"
["displayName"]=>
string(5) "girl1"
["z"]=>
string(5) "34000"
["id"]=>
string(8) "20014794"
["isUgc"]=>
string(0) ""
}
...
If this is the output you want :-
Array
(
[0] => Array
(
[url] => http://assets.zwinky.com/assets/babe/heads/01/head1
[c] => 0xF4C4A4
[c2] => 0xffffff
[displayName] =>
[z] => 33000
[id] =>
[isUgc] =>
)
[1] => Array
(
[url] => http://assets.zwinky.com/assets/babe/faces/01/grl1
[c] => 0x0
[c2] => 0xFF0000
[displayName] => girl1
[z] => 34000
[id] => 20014794
[isUgc] =>
)
[2] => Array
(
[url] => http://assets.zwinky.com/assets/babe/midsections/01/ms1
[c] => 0xBCE4FE
[c2] =>
[displayName] =>
[z] => 9000
[id] =>
[isUgc] =>
)
... etc etc
Then all you need to do is change the code to this
public static function get_outfits($username) {
$files = self::user_files($username);
$data = self::request($files['outfits']);
$data = #simplexml_load_string($data);
if ( $data && count(#$data->xpath('//outfits/outfit')) > 0 ) {
foreach(#$data->xpath('//outfits/outfit/*') as $items) {
// $response['outfits']['items'][] = array(
$response[] = array(
"url" => (string)$items['url'],
"c" => (string)$items['c'],
"c2" => (string)$items['c2'],
"displayName" => (string)$items['displayName'],
"z" => (string)$items['z'],
"id" => (string)$items['id'],
"isUgc" => (string)$items['isUgc']
);
}
}
return (isset($response) ? $response : false);
}

Move array in array to parent array php

Is there a specific function to move array which is in array to the parent array as key or value.
array(5) { [0]=> array(1) { [0]=> string(2) "id" } [1]=> array(1) { [0]=> string(7)
"buydate" } [2]=> array(1) { [0]=> string(6) "expire" } [3]=> array(1) { [0]=> string(6)
"planid" } [4]=> array(1) { [0]=> string(5) "buyer" } }
Result I would like to get is:
array() { [0] => 'id', [1] => 'buydate' etc. }
Or
array('id', 'buydate' etc.. )
Is it possible to achieve without foreach ?
array_map() is extremely powerful and should do the trick:
$array = ... ; // your initial array
$flattened_array = array_map(function($item) {
return $item[0];
}, $array);
If you want to flatten the desired array, and use foreach you can do it this way.
Consider this example:
// Sample data:
$values = array(
0 => array(
0 => 'id',
),
1 => array(
0 => 'buydate',
),
2 => array(
0 => 'expire',
),
3 => array(
0 => 'planid',
),
4 => array(
0 => 'buyer',
),
);
$new_values = array();
foreach($values as $key => $value) {
$new_values[] = $value[0];
}
print_r($new_values);
Sample Output:
Array
(
[0] => id
[1] => buydate
[2] => expire
[3] => planid
[4] => buyer
)
Or alternatively, you can you the iterator. Consider this example:
$new_values = array();
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($values));
foreach($iterator as $value) {
$new_values[] = $value;
}
It should gave you the same output.

Categories