I am trying to build multidimensional to get json but its getting little complex. Sure there is easier way to do this. Here is my code.
$rows = array();
$idx = 0;
$sql = "SELECT products, GROUP_CONCAT(title,',' ,price SEPARATOR ', ' ) prods FROM mylist GROUP BY products";
$query = mysqli_query($con, $sql);
while($row = mysqli_fetch_assoc($query)){
$rows[$idx]['products'] = $row['products'];
$title = explode(',',$row['prods']);
$rows[$idx]['prods'] = $title;
$idx++;
};
echo '<pre>' . var_export($rows, true) . '</pre>';
echo json_encode($rows);
It give me this result
array (
0 =>
array (
'prods' =>
array (
0 => 'title 4',
1 => '4',
2 => ' title 1',
3 => '1',
),
),
1 =>
array (
'prods' =>
array (
0 => 'title 2',
1 => '21',
),
),
2 =>
array (
'prods' =>
array (
0 => 'title 3',
1 => '3',
),
),
)
[{"prods":["title 4","4"," title 1","1"]},{"prods":["title 2","21"]},{"prods":["title 3","3"]}]
But I want like this
array (
0 =>
array (
'prods' =>
array (
array(title => 'title 4', price => '4'),
array(title => ' title 1', price => '1'),
),
),
1 =>
array (
'prods' =>
array (
array(title => 'title 2', price => '21'),
),
),
2 =>
array (
'prods' =>
array (
array(title => 'title 3', price => '3'),
),
),
)
[
{
"prods": [
{
"title": "title 4",
"price": "4"
},
{
"title": "title1",
"price": "1"
}
]
},
{
"prods": [
{
"title": "title2",
"price": "21"
}
]
},
{
"prods": [
{
"title": "title3",
"price": "3"
}
]
}
]
So, not sure how to mix the exploded data on array to get the right json encoded.
You can do a foreach on the $title array and if the key is even then build the output array with the desired keys. In the below I edited to substituted your db query for json so that the full example can be included without the sql query.
$rows = array();
$idx = 0;
$data = json_decode('[{"products":"the product", "prods":"title 4,4,title 1,1"},{"products":"the product", "prods":"title 2,21"},{"products":"the product", "prods":"title 3,3"}]', true);
foreach ($data as $row)
{
$rows[$idx]['products'] = $row['products'];
$title = explode(',',$row['prods']);
foreach ($title as $k => $v) {
// check if even
if ($k % 2 == 0) $rows[$idx]['prods'][] = array('title' => $v, 'price' => $title[$k+1]);
}
$idx++;
};
echo '<pre>' . var_export($rows, true) . '</pre>';
echo json_encode($rows);
Will output the following
array (
0 =>
array (
'products' => 'the product',
'prods' =>
array (
0 => array ('title' => 'title 4','price' => '4'),
1 => array ('title' => 'title 1','price' => '1'),
),
),
1 =>
array (
'products' => 'the product',
'prods' =>
array (
0 => array ('title' => 'title 2','price' => '21'),
),
),
2 =>
array (
'products' => 'the product',
'prods' =>
array (
0 => array ('title' => 'title 3','price' => '3'),
),
),
)
Based on Tristan earlier suggestion, I was able to get the expected result with below code, not sure if that's the best way.
$rows = array();
$idx = 0;
$sql = "SELECT products, GROUP_CONCAT(title,',',price SEPARATOR ';') prods FROM mylist GROUP BY products";
$query = mysqli_query($con, $sql);
while($row = mysqli_fetch_assoc($query)){
$prods = explode(';',$row['prods']);
foreach ($prods as $key => $value) {
$expValue = explode(',',$value);
$rows[$idx]['prods'][] = array('title' => $expValue[0], 'price' => $expValue[1]);
};
$idx++;
};
echo '<pre>' . var_export($rows, true) . '</pre>';
echo json_encode($rows);
Related
What I'm trying to accomplish is to write a html string in a controller with array values being looped in it. So for example;
$content = "Your store, at location A, has these items added to them". add array loop here. "Do take note!";
My array would be as such
array (
0 =>
array (
'id' => '5db29b6d31c391731239bbdf',
'name' => 'Diamond bracelet (sample)',
'tags' =>
array (
0 => 'female',
1 => 'jewelry',
),
'category' => 'Accessories',
'sku' => '1029EHW',
'priceType' => 'Fixed',
'unitPrice' => 190,
'cost' => 90,
'trackStockLevel' => true,
'isParentProduct' => false,
),
1 =>
array (
'id' => '5db29b6d31c391731239bbdb',
'name' => 'Long-sleeved shirt(sample)(M)',
'tags' =>
array (
0 => 'tops',
1 => 'cotton',
),
'category' => 'Women\'s Apparel',
'sku' => 'ABC1234-M',
'priceType' => 'Fixed',
'unitPrice' => 47.170000000000002,
'cost' => 20,
'trackStockLevel' => true,
'isParentProduct' => false,
'parentProductId' => '5db29b6d31c391731239bbd4',
'variationValues' =>
array (
0 =>
array (
'variantGroupId' => '5db29b6d31c391731239bbd5',
'value' => 'M',
),
),
),
)
note that the array can have many instances of product_name and sku, or can have none.
How do i populate this in my string to be like;
$content = "Your store, at location A, has these items added to them, 1) asd, 2)def, 3)asf . Do take note!
Try this, I've used \sprintf for ease, check if the output serves your purpose.
<?php
function stringMethod(): string
{
$count = 0;
$arrayString = [];
$array = [['product_name' => 'abc', 'product_sku' => 'def'],['product_name' => 'abc', 'product_sku' => 'asd']];
foreach ($array as $value){
$count++;
$arrayString[] = sprintf('%s)%s', $count, $value['product_sku']);
}
$string = \implode(',', $arrayString);
return \sprintf("Your store, at location A, has these items added to them %s Do take note!", $string);
}
echo stringMethod();
Hope this will help you. try to do it in less number of lines
$content = "Your store, at location A, has these items added to them, ";
$productArray = array (0 => array ('id' => '5db29b6d31c391731239bbdf','name' => 'Diamond bracelet (sample)','tags' => array (0 => 'female',1 => 'jewelry',),'category' => 'Accessories','sku' => '1029EHW','priceType' => 'Fixed','unitPrice' => 190,'cost' => 90,'trackStockLevel' => true,'isParentProduct' => false,),1 => array ('id' => '5db29b6d31c391731239bbdb','name' => 'Long-sleeved shirt(sample)(M)','tags' => array (0 => 'tops',1 => 'cotton',),'category' => 'Women\'s Apparel','sku' => 'ABC1234-M','priceType' => 'Fixed','unitPrice' => 47.170000000000002,'cost' => 20,'trackStockLevel' => true,'isParentProduct' => false,'parentProductId' => '5db29b6d31c391731239bbd4','variationValues' => array (0 => array ('variantGroupId' => '5db29b6d31c391731239bbd5','value' => 'M'))));
foreach ($productArray as $key => $product) {
$content .= ($key+1).') '.$product['name'];
if (count($productArray)-1!=$key) {
$content .= ', ';
}
}
$content .= ". Do take note!";
$content = "Your store, at location A, has these items added to them,". $this->getItemList($collection) .". Do take note!"
# Somewhere else in the controller
protected function getItemList(Collection $collection): string
{
return $collection->pluck('name')
->merge($collection->pluck('sku'))
->map(function($item, $key) {
return ($key + 1) . ') ' . $item;
})
->implode(', ');
}
An easy solution would be
$content = "Your store, at location A, has these items added to them";
$array = array(0=>["product_name" => "abc", "product_sku" => "def"], 1=>['product_name' => 'kdkf', 'product_sku'=> 'ljbkj']);
for($i = 0; $i<count($array); $i++){
$content .= ($i+1).") ".$array[$i]['product_name].' '.$array[$i]['product_sku'].', ';
}
$content .= "Do take note.";
This way you're just constantly concatonating the string value in separate parts instead of trying to inject it in the middle of the parent string.
not tested, may be syntax errors
I have the following bibliography data in an array (note that fields are in random order - there are others fields as well):
Array
(
[0] => Array
(
['Pub_Name'] => Nature
['Volume'] => 6
['Pages'] => 215-217
)
[1] => Array
(
['Volume'] => 15
['Pages'] => 358-360
['Pub_Name'] => Science
)
[2] => Array
(
['Pub_Name'] => PNAS
['Pages'] => 17-19
['Volume'] => 22
)
)
I want to "merge" those three fields into one, for example ['Pub_Name']=Nature, 6: 215-217. I tried the following whitout success (I guess $Record['Pub_Name'] is the incorrect sintax):
foreach ($MyArray as $Record) {
foreach ($Record as $key => $values) {
if ($key=="Volume") {$Volumen=", ".$values;} else {$Volumen="";}
if ($key=="Pages") {$Paginas=": ".$values;} else {$Paginas="";}
}
//This is the line for which I want to know the sintax!!
$Record['Pub_Name'].=$Volumen.$Paginas;
}
No need for two loops:
foreach ($MyArray as $Record) {
$result[]['Pub_Name'] = "{$Record['Pub_Name']}, {$Record['Pages']}: {$Record['Volume']}";
}
Then you have the new Pub_Name entries in $result.
If you want to modify the original then reference & $Record:
foreach ($MyArray as &$Record) {
$Record['Pub_Name'] = "{$Record['Pub_Name']}, {$Record['Pages']}: {$Record['Volume']}";
}
Or use the key and modify the original array:
foreach ($MyArray as $key => $Record) {
$MyArray[$key]['Pub_Name'] = "{$Record['Pub_Name']}, {$Record['Pages']}: {$Record['Volume']}";
}
PHP code demo
<?php
$array=Array
(
0 => Array
(
'Pub_Name' => "Nature",
'Volume' => 6,
'Pages' => "215-217"
),
1 => Array
(
'Volume' => 15,
'Pages' => "358-360",
'Pub_Name' => "Science"
),
2 => Array
(
'Pub_Name' => 'PNAS',
'Pages' => "17-19",
'Volume' => 22
)
);
$result=array();
foreach ($array as $data)
{
$result[]=array('Pub_Name'=> $data['Pub_Name'].", ".$data["Volume"].": ".$data["Pages"]);
}
print_r($result);
Output:
Array
(
[0] => Array
(
[Pub_Name] => Nature, 6: 215-217
)
[1] => Array
(
[Pub_Name] => Science, 15: 358-360
)
[2] => Array
(
[Pub_Name] => PNAS, 22: 17-19
)
)
I guess this is what you are looking for:
<?php
$input = [
[
'Pub_Name' => 'Nature',
'Volume' => '6',
'Pages' => '215-217'
],
[
'Volume' => '15',
'Pages' => '358-30',
'Pub_Name' => 'Science',
],
[
'Pub_Name' => 'PNAS',
'Pages' => '17-19',
'Volume' => '22'
]
];
$output = [];
array_walk($input, function ($entry) use (&$output) {
$output[] = sprintf(
'%s, %s: %s',
$entry['Pub_Name'],
$entry['Volume'],
$entry['Pages']
);
});
print_r($output);
The output of above code obviously is:
Array
(
[0] => Nature, 6: 215-217
[1] => Science, 15: 358-30
[2] => PNAS, 22: 17-19
)
Use array_map
$in = [
0 => [
'Pub_Name' => 'Nature',
'Volume' => 6,
'Pages' => '215-217'
],
1 => [
'Volume' => 15,
'Pages' => '358-360',
'Pub_Name' => 'Science',
],
2 => [
'Pub_Name' => 'PNAS',
'Pages' => '17-19',
'Volume' => 22
]
];
array_map(function ($item) {
return $item['Pub_Name'] . ', ' . $item['Volume'] . ': ' . $item['Pages'];
}, $in);
There are a few different ways to do this - but one of the more readable ways:
// create a copy of the original - so we aren't looping thru the same array we're updating
$updatedArray = $MyArray;
foreach ($MyArray as $index => $record) {
$updatedArray[$index]['Pub_Name'] =
$record['Pub_Name'].
($record['Volume'] ? ', '.$record['Volume'] : '').
($record['Pages'] ? ': '.$record['Pages']:'');
}
Clear way in a single loop. Use sprintf() for easy formatting:
<?php
$src =[ ['Pub_Name' => 'Nature', 'Volume' => '6', 'Pages' => '215-217'],
['Volume' => '15', 'Pages' => '358-30', 'Pub_Name' => 'Science'],
['Pub_Name' => 'PNAS', 'Pages' => '17-19', 'Volume' => '22']
];
foreach ($src as $element) {
$dest[] = sprintf("%s, %d: %s",
$element['Pub_Name'],
$element['Volume'],
$element['Pages']);
}
var_dump($dest);
?>
And you get:
array(3) {
[0]=> string(18) "Nature, 6: 215-217"
[1]=> string(19) "Science, 15: 358-30"
[2]=> string(15) "PNAS, 22: 17-19"
}
Test it here.
This should help:
$combined = [];
foreach($myArray as $pub) {
$combined.push($pub['Pub_Name'] . ', ' . $pub['Volume'] . ': ' . $pub['Pages']);
}
I'm have time overlap check inside while loop and I would also like to display events title with results which is in another array.
Without double foreach loop I can echo $event->title; and it displays all event titles. If I put array $event which has $event->title, inside foreach which I have for overlap testing it only displays first title.
I'm newbie PHP and I'm banging my head with complete solution for a couple of days now. Any help would be awesome :(
while (list(,$event_row) = each($events)) {
$event->loadEvent($event_row[0]);
foreach ($events as $thisevent) {
$event_array = array($event->id,$event->title);
$conflicts = 0;
foreach ($events as $thatevent) {
if ($thisevent[0] === $thatevent[0]) {
continue;
}
$thisevent_from = $thisevent[1];
$thisevent_ends = $thisevent[2];
$thatevent_from = $thatevent[1];
$thatevent_ends = $thatevent[2];
if ($thatevent_ends > $thisevent_from AND $thisevent_ends > $thatevent_from) {
echo $event->title;
$conflicts++;
echo "Event #" . $thisevent[0] . " overlaps with Event # " . $thatevent[0] . "\n";
}
}
if ($conflicts === 0) {
echo "Event #" . $thisevent[0] . " is OK\n";
}
}
}
Without double foreach var_export($event) displays all event arrays.
array( 'title' => 'Event 1', 'description' => 'Event description 1', 'contact' => 'event contact 1', 'url' => '', 'link' => '', 'email' => 'event#eventemail.com', 'picture' => '', 'color' => '#009933', 'catName' => 'Events', 'catDesc' => 'General events', 'startDate' => 1432918800, 'endDate' => 1432926000, 'startDay' => 29, 'startMonth' => 5, 'startYear' => 2015, 'endDay' => 29, 'endMonth' => 5, 'endYear' => 2015, 'recurStartDate' => NULL, 'recurEndDate' => NULL, 'id' => '11', 'catId' => 1, 'status' => true, 'recType' => '', 'recInterval' => 0, 'recEndDate' => 1432850400, 'recEndType' => 0, 'recEndCount' => 1, ))
And var_export($events) array displays three times all arrays with id, start date and end date:
array ( 0 => array ( 0 => '11', 1 => 1432918800, 2 => 1432926000, ), 1 => array ( 0 => '13', 1 => 1432918800, 2 => 1432926000, ), 2 => array ( 0 => '16', 1 => 1432926000, 2 => 1432929600, ), )
Thank you for looking into it and giving any possible solutions hints, ideas :)
when searching an element in a nested array, could i get back it's 1st level nesting index.
<?php
static $cnt = 0;
$name = 'victor';
$coll = array(
'dep1' => array(
'fy' => array('john', 'johnny', 'victor'),
'sy' => array('david', 'arthur'),
'ty' => array('sam', 'joe', 'victor')
),
'dep2' => array(
'fy' => array('natalie', 'linda', 'molly'),
'sy' => array('katie', 'helen', 'sam', 'ravi', 'vipul'),
'ty' => array('sharon', 'julia', 'maddy')
)
);
function recursive_search(&$v, $k, $search_query){
global $cnt;
if($v == $search_query){
/* i want the sub array index to be returned */
}
}
?>
i.e to say, if i'am searching 'victor', i would like to have 'dep1' as the return value.
Could anyone help ??
Try:
$name = 'victor';
$coll = array(
'dep1' => array(
'fy' => array('john', 'johnny', 'victor'),
'sy' => array('david', 'arthur'),
'ty' => array('sam', 'joe', 'victor')
),
'dep2' => array(
'fy' => array('natalie', 'linda', 'molly'),
'sy' => array('katie', 'helen', 'sam', 'ravi', 'vipul'),
'ty' => array('sharon', 'julia', 'maddy')
)
);
$iter = new RecursiveIteratorIterator(new RecursiveArrayIterator($coll), RecursiveIteratorIterator::SELF_FIRST);
/* These will be used to keep a record of the
current parent element it's accessing the childs of */
$parent_index = 0;
$parent = '';
$parent_keys = array_keys($coll); //getting the first level keys like dep1,dep2
$size = sizeof($parent_keys);
$flag=0; //to check if value has been found
foreach ($iter as $k=>$val) {
//if dep1 matches, record it until it shifts to dep2
if($k === $parent_keys[$parent_index]){
$parent = $k;
//making sure the counter is not incremented
//more than the number of elements present
($parent_index<$size-1)?$parent_index++:'';
}
if ($val == $name) {
//if the value is found, set flag and break the loop
$flag = 1;
break;
}
}
($flag==0)?$parent='':''; //this means the search string could not be found
echo 'Key = '.$parent;
Demo
This works , but I don't know if you are ok with this...
<?php
$name = 'linda';
$col1=array ( 'dep1' => array ( 'fy' => array ( 0 => 'john', 1 => 'johnny', 2 => 'victor', ), 'sy' => array ( 0 => 'david', 1 => 'arthur', ), 'ty' => array ( 0 => 'sam', 1 => 'joe', 2 => 'victor', ), ), 'dep2' => array ( 'fy' => array ( 0 => 'natalie', 1 => 'linda', 2 => 'molly', ), 'sy' => array ( 0 => 'katie', 1 => 'helen', 2 => 'sam', 3 => 'ravi', 4 => 'vipul', ), 'ty' => array ( 0 => 'sharon', 1 => 'julia', 2 => 'maddy', ), ), );
foreach($col2 as $k=>$arr)
{
foreach($arr as $k1=>$arr2)
{
if(in_array($name,$arr2))
{
echo $k;
break;
}
}
}
OUTPUT :
dept2
Demo
I have an array:
$settings = array(
'name' => array(
0 => 'Large Pouch',
1 => 'XL Pouch'
),
'size' => array(
0 => '9x14',
1 => '12x18'
),
'weight' => array(
0 => '10',
1 => '20'
),
'metro_manila_price' => array(
0 => '59',
1 => '79'
),
'luzvimin_price' => array(
0 => '89',
1 => '139'
)
);
I wanted to put the values from that array to one array. $shipping_options with format of
for example:
$shipping_options = array(
'0' => 'Large Pouch 9x14 - $59',
'1' => 'XL Pouch 12x18 - $79'
);
How to program this?
You could write a loop:
$shipping_options = array();
foreach ($settings['name'] as $key => $value) {
$value = sprintf('%s(%s) - $%s',
$value,
$settings['size'][$key],
$settings['metro_manila_price'][$key]);
$shipping_options[$key] = $value;
}
try this one
echo "<pre>";
$size = count($settings['name']);
$shipping_options = array();
for($i=0; $i<$size; $i++)
{
$shipping_options[$i] = $settings['name'][$i]."(".$settings['size'][$i].") - $".$settings['metro_manila_price'][$i];
}
print_r($shipping_options);
You can try this
foreach ($settings['name'] as $key => $value) {
$shipping_options[$key] = $settings['name'][$key] . " " . $settings['size'][$key] . " - $" . $settings['metro_manila_price'][$key];
}