First of all, my grouping is working but I feel it is dirty. Need someone to make it looks
clean and better.
I have following foreach
$data['new_array'] = array(); //I have to use $data['new_array'] because I need to pass it to template.
foreach ($get_topics as $topic) {
//Is that possible to make these 4 lines shorter?
$data['new_array'][$topic['tid']]['tid'] = $topic['tid'];
$data['new_array'][$topic['tid']]['title'] = $topic['title'];
$data['new_array'][$topic['tid']]['yes'] = $topic['yes'];
$data['new_array'][$topic['tid']]['no'] = $topic['no'];
//The belows are subarray grouping, it actually works but I need better solutions
//$new_array[$topic['tid']]['vid'][$topic['vid']][] = $topic['vid'];
//$new_array[$topic['tid']]['vid'][$topic['vid']][] = $topic['yesno'];
}
I wouldn't even try to make it shorter, but here's your code in a good looking version.
$data['new_array'] = array();
foreach ($get_topics as $topic) {
$data['new_array'][$topic['tid']] = array(
'tid' => $topic['tid'],
'title' => $topic['title'],
'yes' => $topic['yes'],
'no' => $topic['no']
);
}
Not sure what type is $topic['tid'] but you should be careful when using non-consecutive numbers as array keys.
Related
I am trying to assemble an array of objects from a variety of sources in PHP (I'm new to the language). The problem is that I am not able to store the data within the $bandwidthData array in the foreach loop I am trying to write.
private function _getData($startDay, $totalDays)
{
$devices = ubntDevices::getDevices();
$data = [];
$bandwidthData = [];
$count = 0;
foreach ($devices as $device) {
$bandwidthData[$count]['device'] = $device;
$bandwidthData[$count]['bandwidth'] = new ubntModel($device->file);
$bandwidthData[$count]['bandwidth']->getMonthData();
$bandwidthData[$count]['tree'] = new graphTree($device->hostid);
$bandwidthData[$count]['graphid'] = ubntGraph::getGraphByHostId($device->hostid);
$bandwidthData[$count]['hostname'] = $device->host_name;
$count++;
}
return $bandwidthData;
}
If I return from within the foreach loop, I get the correct output (but obviously for only the first device). I have tested all of the other function sources, and they seem to be returning the right data. Any idea what I could be doing wrong? Thank you in advance.
Your PHP error log should indicate what's going wrong. XDebug is very highly recommended as well.
However, nowadays it is more common to use an associative array like this:
private function _getData($startDay, $totalDays)
{
$devices = ubntDevices::getDevices();
$bandwidthData = [];
foreach ($devices as $device) {
$ubntModel = new ubntModel($device->file);
$deviceData = array('device' => $device,
'ubntModel' => $ubntModel,
'bandwidth' => $ubntModel->getMonthData(),
'tree' => new graphTree($device->hostid),
'graphid' => ubntGraph::getGraphByHostId($device->hostid),
'hostname' => $device->host_name);
$bandwidthData[] = $deviceData;
}
return $bandwidthData;
}
Some things I'm seeing:
Is this variable in use?
$data = [];
Also, this assignment runs but is a discouraged approach because at this point $bandwidthData[$count] does not exist:1
$bandwidthData[$count]['device'] = $device;
That can be converted to:
$bandwidthData[$count] = [ 'device' => $device ];
Also, this just a getter returning nowhere. Isn't it?
$bandwidthData[$count]['bandwidth']->getMonthData();
Also to further learn PHP I can suggest such cleaner approach for that code snippet, just to improve readability:
private function _getData( $startDay, $totalDays ) {
$bandwidthData = [];
foreach ( ubntDevices::getDevices() as $device ) {
$bandwidthData[] = [
'device' => $device,
'bandwidth' => new ubntModel( $device->file ),
'tree' => new graphTree( $device->hostid ),
'graphid' => ubntGraph::getGraphByHostId( $device->hostid ),
'hostname' => $device->host_name,
];
}
return $bandwidthData;
}
Anyway you have to learn how to debug that simple small block of code just looking at your server logs, or with a lazy var_dump( $bandwidthData[ $count ] ) in your suspected line (do not fight about this debugging approach: it's super stupid, but dramatically simple and effective, and friendly for newcomers - if you have not the possibility to setup a debugger because maybe the server is not yours etc.) or setting up a debugger.
1 from https://www.php.net/manual/en/language.types.array
If $arr doesn't exist yet, it will be created, so this is also an alternative way to create an array. This practice is however discouraged because if $arr already contains some value (e.g. string from request variable) then this value will stay in the place and [] may actually stand for string access operator. It is always better to initialize a variable by a direct assignment
I have those two arrays that I added to attachments.
"PartnerAffiliateCodeId" from first array and "Id" from second array is our primary key.
"UserAction" must be counted for every unique "PartnerAffiliateCodeId" so in our case it is 5.
Normally I think this must be done by SQL but unfortunately this is a API method that I am receiving so I have to handle it by PHP.
Any ideas about how I can make such join with PHP using these two arrays?
I'm unclear on exactly what you're trying to get at with UserAction, but you could try something like this:
//$array1 = the first array
//$array2 = the second array
array_push($array_1, array(
"DateTime" => "",
"HttpReferer" => "",
"Id" => count($array1),
"PartnerAffiliateCodeId" => $array2["Id"],
"UserAction" => "Click"
));
It sounds like you want to match the ID key to the PartnerAffiliateCodeId in your returned data set.
Without knowing your setup, or bothinging with total optimization here a workable solution which will give you some direction.
function selectPartnerWhere($id=null; $from=array())
{
$codes = array();
foreach($from as $k => $p)
{
if($id == $p['PartnerAffiliateCodeId'])
{
return $from[$k];
}
}
return array();
}
$theData = //your array above
$thePartner = //your partner above
$partnerData = selectPartnerWhere($thePartner['Id'], $theData);
I have encountered this case many times in my work, need to get an sub-array with specific keys from an array. Today I want to make it a better performance, So my question is which is the better option:
Sample Option 1:
$where_requires = array('group_id', 'name');
$item = array('group_id' => 2, 'name' => 'Bob', 'age' => 37);
$where = array_diff_key($item, array_diff_key($item, array_fill_keys($where_requires, '')));
Sample Option 2
$where = array();
foreach($where_requires as $require){
$where[$require] = $item[$require];
}
Remeber that both $where and $where_require is a big array, about hundreds elements. The timing cost at my machine make no obvious difference, Could you give me some advice? Better explainning why. Thanks all who notice my question.
Try with:
$where = array_intersect_key($item, array_flip($where_requires));
I have an array structured like this:
$arrNames = array(
array('first'=>'John', 'last'=>'Smith', 'id'=>'1'),
array('first'=>'John', 'last'=>'Smith', 'id'=>'2'),
array('first'=>'John', 'last'=>'Smith', 'id'=>'3')
)
I need to remove the similar elements where the fist and last name are the same. Normally, I would use array_unique but the elements aren't exactly unique since each one has a unique id. I do not care which id is retained. I just need the array to look like this:
$arrNames = array(
array('first'=>'John', 'last'=>'Smith', 'id'=>'1') // can be any id from the original array
)
Is there a quick way to accomplish this? My first thought is to use something like a bubble sort but I'm wondering if there is a better (faster) way. The resulting array is being added to a drop-down list box and the duplicate entries is confusing some users. I'm using the ID to pull the record back from the DB after it is selected. Therefore, it must be included in the array.
<?php
$arrNames = array(
array('first'=>'John', 'last'=>'Smith', id=>'1'),
array('first'=>'John', 'last'=>'Smith', id=>'2'),
array('first'=>'John', 'last'=>'Smith', id=>'3')
);
$arrFound = array();
foreach ($arrNames as $intKey => $arrPerson) {
$arrPersonNoId = array(
'first' => $arrPerson['first'],
'last' => $arrPerson['last']
);
if (in_array($arrPersonNoId, $arrFound)) {
unset($arrNames[$intKey]);
} else {
$arrFound[] = $arrPersonNoId;
}
}
unset($arrFound, $intKey, $arrPerson, $arrPersonNoId);
print_r($arrNames);
This definitely works, whether it is the best way is up for debate...
Codepad
There is no fast and easy way that I know of, but here is a relatively simple way of doing it assuming that the ids for "similar elements" don't matter (i.e. you just need an ID period).
$final = array();
foreach ($array as $values) {
$final[$values['first'] . $values['last']] = $values;
}
$array = array_values($final);
The last step is not strictly necessary .. only if you want to remove the derived keys.
$mainMenu['Home'][1] = '/mult/index.php';
$mainMenu['Map'][1] = '/mult/kar.php';
$mainMenu['MapA'][2] = '/mult/kara.php';
$mainMenu['MapB'][2] = '/mult/karb.php';
$mainMenu['Contact'][1] = '/mult/sni.php';
$mainMenu['Bla'][1] = '/mult/vid.php';
This is a menu, 1 indicates the main part, 2 indicates the sub-menu. Like:
Home
Map
-MapA
-MapB
Contat
Bla
I know how to use foreach but as far as I see it is used in 1 dimensional arrays. What I have to do in the example above?
You would need to nest two foreach BUT, there is nothing about your data structure that easily indicates what is a sub-item. Map vs. MapA? I guess a human could figure that out, but you'll have to write a lot of boilerlate for your script to sort that.. Consider restructuring your data so that it more closely matches what you are trying to achieve.
Here's an example. You can probably come up with a better system, though:
$mainMenu = array(
'Home' => '/mult/index.php',
'Map' => array(
'/mult/kar.php',
array(
'MapA' => '/mult/kara.php',
'MapB' => '/mult/karb.php'
)
),
'Contact' => '/mult/sni.php',
...
);
You nest foreach statements; Something like this should do the work.
foreach($mainMenu as $key=>$val){
foreach($val as $k=>$v){
if($k == 2){
echo '-' . $key;
}else{
echo $key;
}
}
}
Foreach can just as easily be used in multi-dimensional arrays, the same way you would use a for loop.
Regardless, your approach is a little off, here's a better (but still not great) solution:
$mainMenu['Home'][1] = '/mult/index.php';
$mainMenu['Map'][1] = '/mult/kar.php';
$mainMenu['Map']['children']['MapA'] = '/mult/kara.php';
$mainMenu['Map']['children']['MapB'] = '/mult/karb.php';
$mainMenu['Contact'][1] = '/mult/sni.php';
$mainMenu['Bla'][1] = '/mult/vid.php';
foreach($mainMenu as $k => $v){
// echo menu item
if(isset($v['children'])){
foreach($v['children'] as $kk => $vv){
// echo submenu
}
}
}
That said, this only does 1-level of submenus. Either way, it should help you get the idea!