Arranging array in php - php

my problem is i can't arrange the array in the structure i want.
array1 and array2 are generated dynamically. as you can see in the array 2 it has a subjectid which is the same in array1, that means, that element is under the subject cpe 305. all elements in the array 2 which has the id of 5 is under the the subject of cpe 305. same logic with cpe 304.
array1:
Array
(
[0] => Array
(
[subjectid] => 5
[subjectcode] => Cpe 305
)
[1] => Array
(
[subjectid] => 4
[subjectcode] => Cpe 304
)
)
array2:
Array
(
[0] => Array
(
[subjectid] => 5
[soid] => 1
[socode] => A
[sodesc] => Ability to apply knowledge of mathematics and science to solve engineering problems
)
[1] => Array
(
[subjectid] => 5
[soid] => 3
[socode] => C
[sodesc] => Ability to design a system, component, or process to meet the desired needs within realistic constraints such as economic, environmental, social, political, ethical, health and safety, manufacturability, and sustainability, in accordance to standards
)
[2] => Array
(
[subjectid] => 5
[soid] => 4
[socode] => D
[sodesc] => Ability to function on multidisciplinary teams
)
[3] => Array
(
[subjectid] => 5
[soid] => 5
[socode] => E
[sodesc] => Ability to identify, formulate, and solve engineering problems
)
[4] => Array
(
[subjectid] => 5
[soid] => 9
[socode] => I
[sodesc] => Recognition of the need for, and an ability to engage in life-long learning
)
[5] => Array
(
[subjectid] => 4
[soid] => 10
[socode] => J
[sodesc] => Knowledge of contemporary issues
)
)
OUTPUT (my desired structure)
Array(
[subjectid] => 5
[subjectcode] => Cpe 305
[sodetails] => array(
[0]=>Array ([soid]=>1
[socode]=>A)
[1]=>Array([soid]=>3
[socode]=>C .....until the last
)
[subjectid] => 4
[subjectcode] => Cpe 305
[sodetails] => array(
[0]=>Array ([soid]=>10
[socode]=>J)
.......until the last
)
what i've tried
this is the code that im testing. i only include few data here in my test code.
$so = array();
$exist = array();
foreach ($this->subject as $key => $value) {
foreach ($this->sodetails as $key2 => $value2) {
if($value['subjectid'] === $value2['subjectid']){
$exist = array(
"subjectid" => $value['subjectid'],
"details" =>array(
"soid" => $value2['soid']
)
);
array_push($so, $exist);
}
}
}

First of all your output array is incorrect. An array cannot have more than one same indexes like "subjectid", "subjectcode". We need to have a different index. It will be wise to use subjectid as index for outer array.
First prepare your outer array as it is array1.
foreach($this->subject as $key => $val){
$myArray[$val['subjectid']]['subjectid'] => $val['subjectid'];
$myArray[$val['subjectid']]['subjectcode'] => $val['subjectcode'];
}
Now iterate your sodetails array.
foreach($this->sodetails as $key => $val){
$temp['soid'] = $val['soid'];
$temp['socode'] = $val['socode'];
array_push($myArray[$val['subjectid']]['sodetails'], $temp);
}
There can be other ways too. But it is my style and I believe it will solve your problem.

You just need to pass subjectid as key in your return array,
$exist = array();
foreach ($this->subject as $key => $value) {
foreach ($this->sodetails as $key2 => $value2) {
if($value['subjectid'] === $value2['subjectid']){
$exist[$value['subjectid']]['subjectid'] = $value['subjectid'];
$exist[$value['subjectid']]['subjectcode'] = $value['subjectcode'];
$exist[$value['subjectid']]['sodetails'] = array(array('soid'=>$value2['soid']),array('socode'=>$value2['socode']));
}
}
}

Instead of running the loop/iterations for m x n times, what you could do is first have the subjectid as the key for the $arrray1 and let the natural PHP array key handling do the job.
$new_array1 = array();
foreach($arrray1 as $item){
$new_array1[$item['subjectcode']] = $item;
}
foreach($array2 as $desc){
if(array_key_exists($desc['subjectid'],$new_array1){
$new_array1[$desc['subjectid']]['desc'][] = $desc;
}
}
This way you only have to make m + n iterations.

Related

Sum parts of an array in php

this is quite beyond me. Appreciate some help.
I have an array in php like so:
[0] => Array
(
[cust_id] => 1006
[no_of_subs] => 2
[dlv_id] => 1000
)
[1] => Array
(
[cust_id] => 1011
[no_of_subs] => 3
[dlv_id] => 1000
)
[2] => Array
(
[cust_id] => 1012
[no_of_subs] => 5
[dlv_id] => 1001
)
[3] => Array
(
[cust_id] => 1013
[no_of_subs] => 6
[dlv_id] => 1001
)
I don't need the cust_id field. I just need to group the dlv_id and the sum of no_of_subs for each matching dlv_id. The result should look like this:
[0] => Array
(
[dlv_id] => 1000
[no_of_subs] => 5
)
[1] => Array
(
[cust_id] => 1011
[no_of_subs] => 11
)
Thank you for any help.
I don't understand the downvotes for this question. Am i doing it all wrong? Downvoting without a reason is not helping.
The simplest, most efficient way to group and sum is to perform a single loop and assign temporary associative keys.
When a row is identified as a new dlv_id row, save the two desired elements, otherwise add the no_of_subs value to the pre-existing value.
Optionally, remove the temporary keys with array_values().
Code (Demo)
$array = [
["cust_id" => 1006, "no_of_subs" => 2, "dlv_id" => 1000],
["cust_id" => 1011, "no_of_subs" => 3, "dlv_id" => 1000],
["cust_id" => 1012, "no_of_subs" => 5, "dlv_id" => 1001],
["cust_id" => 1013, "no_of_subs" => 6, "dlv_id" => 1001]
];
foreach ($array as $row) {
if (!isset($result[$row["dlv_id"]])) {
$result[$row["dlv_id"]] = ["dlv_id" => $row["dlv_id"], "no_of_subs" => $row["no_of_subs"]];
} else {
$result[$row["dlv_id"]]["no_of_subs"] += $row["no_of_subs"];
}
}
var_export(array_values($result));
Output:
array (
0 =>
array (
'dlv_id' => 1000,
'no_of_subs' => 5,
),
1 =>
array (
'dlv_id' => 1001,
'no_of_subs' => 11,
),
)
Using array_column function, we can extract out dlv_id and no_of_subs separately in two different arrays, using cust_id as the key.
Now, simply loop over the array of dlv_id, and if matching key found, add the no_of_subs to it, else set the value (for the first time).
We use isset function to check if the key exists already or not.
Try the following:
// your input array is $input_array
// get all dlv_id maintaining the cust_id as index
$dlv_id = array_column($input_array, 'dlv_id', 'cust_id');
// get all no_of_subs maintaining the cust_id as index
$no_of_subs = array_column($input_array, 'no_of_subs', 'cust_id');
$output = array();
foreach ($dlv_id as $key => $value) {
if (isset($output[$value]['dlv_id'])) {
$output[$value]['dlv_id'] += $no_of_subs[$key];
} else {
$output[$value]['dlv_id'] += $no_of_subs[$key];
}
}

merge/sum multi dimentional array php

I'm trying to merge/sums 2 arrays that can contain integers or more arrays (themselves containing integer).
When the values are integers, I need to sum them in the final array.
When the values are arrays, I need to loop through the values and sum them in the final array.
If a value or a sub-array exists only in 1 of the base array, it needs to be added in the sub-array of the final array. (This is what I can't do)..)
My arrays are like this:
ARRAY 1
[1466859600] => Array
(
[TOTAL] => 27217
[AAA] => Array
(
[FD_CDP] => 1746
[LO_SC_MIC] => 4654
[FD_ATS] => 893
[CDP] => 40
[SUPERVISION] => 9
[CONTROL] => 4
[ATS] => 4
[EVT_ACK] => 3
)
[BBB] => Array
(
[FD_CDP] => 1376
[LO_SC_MIC] => 4606
[FD_ATS] => 826
[FD_ATSS] => 451
[LO_SFRC] => 4
[FD_S2] => 259
[2_LOSC] => 2
)
[CCC] => Array
(
[FD_CDP] => 1333
[LO_SC_MIC] => 4725
[FD_ATS] => 856
[CONTROL] => 4
[ATS] => 2
[EVT_ACK] => 5
)
ARRAY 2
[1466859600] => Array
(
[TOTAL] => 95406
[AAA] => Array
(
[FD_ATSS] => 1719
[LO_SC_MIC] => 16830
[CONTROL] => 16
[NEW] => 7
[NOEL] => 206
)
[BBB] => Array
(
[SUPERVISION] => 23
[CDP] => 158
[CONTROL] => 40
[2_LOSC] => 14
[ATS] => 6
[EVT_ACK] => 4
)
[CCC] => Array
(
[EVT_ACK] => 167
[LO_SFRC] => 248
[SUPERVISION] => 23
)
I wrote a function like this :
function sumArrayValues($array1, $array2)
{
foreach ($array1 as $key => $value)
{
if (is_array($array1[$key]))
{
echo "it's an array\n I need to reloop\n";
sumArrayValues($array1[$key], $array2[$key]);
}
else
{
echo "FIRST VALUE TO SUM\n";
print_r($array1[$key]."\n");
echo "SECOND VALUE TO SUM\n";
print_r($array2[$key]."\n");
$array1[$key] = (int)$array1[$key] +(int)$array2[$key];
echo "--------RESULT of SUM array1&2----------\n";
}
}
return $array1;
}
But this function doesn't take into account 2 (and probably more) cases: if the sub-array are not in the same order, if a sub-array or a value only exist in second array.
A example of function would be a good help, but on a more fundamental level, I even can't figure the algorithm to do that.
Any ideas ?
You can get all the keys for the foreach loop, live demo.
Note, you also can check if a key of any array is undefined, then save the defined value for the key.
function sumArrayValues($array1, $array2)
{
$keys = array_keys($array1 + $array2);
foreach ($keys as $key)
{
if (is_array($array1[$key]) || is_array($array2[$key]))
$array1[$key] = sumArrayValues($array1[$key], $array2[$key]);
else
#$array1[$key] = (int)$array1[$key] +(int)$array2[$key];
}
return $array1;
}

Draw a Google Chart with undefined number of lines

I need to draw a Google Chart with an undefined number of lines (rows). Lets suppose I need to draw the number of goals of two teams in a certain day (the number of teams is fixed for the example, but it could be anyone, the number of days are the same for all teams). I have this array:
Array
(
[team1] => Array
(
[0] => Array
(
[day] => 1
[goals] => 3
)
[1] => Array
(
[day] => 2
[goals] => 1
)
[2] => Array
(
[day] => 3
[goals] => 0
)
)
[team2] => Array
(
[0] => Array
(
[day] => 1
[goals] => 1
)
[1] => Array
(
[day] => 2
[goals] => 2
)
[2] => Array
(
[day] => 3
[goals] => 4
)
)
)
I have tried creating this loop:
$resultArray = array();
$resultArray['cols'][] = array('label' => "Day", 'type' => 'string');
// $array is the one shown before
foreach($array as $key => $chartData){
$resultArray['cols'][] = array('label' => $key, 'type' => 'number');
foreach($chartData as $data){
$resultArray['rows'][] = array('c' => array( array('v' => $data['day']), array('v' => $data['goals'])));
}
}
The problem is that the chart only draws one line with the data from both teams joined all together instead two lines one for each team.
I would really appreciate any help.
I think your making it harder on yourself using associative arrays for google chart data. The data structure of your array is also adding some challenges to the loop making it a bit more challenging to get the data out in the desired format:
$chartData = array();
$chartData[] = array("Day");
foreach($array as $key => $a){
$chartData[0][] = $key;
for($i = 0; $i < count($a); $i++){
if(!is_array($chartData[$i+1])){
$chartData[$i+1] = array();
$chartData[$i+1][] = $a[$i]['day'];
}
$chartData[$i+1][count($chartData[0])-1] = $a[$i]['goals'];
}
}
This should give you the format you need to have the desired chart data table:
[
["Day","team1","team2"]
[1,3,1]
[2,1,2]
[3,0,4]
]
Creating a line for the number of goals (y Axis) for each team over the number of days (x axis). Hope this helps

PHP: A clean way of converting an array

What is a clean way to convert an array that looks like this:
[584] => Array ( [link_id] => 1 [site_id] => 5 [COUNT(*)] => 2 )
[585] => Array ( [link_id] => 243 [site_id] => 5 [COUNT(*)] => 2 )
[586] => Array ( [link_id] => 522 [site_id] => 89223 [COUNT(*)] => 3 )
To an array where the key is the site_id from above, so for the above example the resulting array would be:
[5] => Array( 1, 2, 243, 2) //Even ones and 0 are link_id, odd ones are count(*)
[89223] => Array(522, 3)
So, basically, group them by site_id. I still need to keep the relationship between link_id and count(*), in the case above I am doing it by the positions (so 0 and 1 are together, 2 and 3, etc) but I am open to a new structure as well.
Thanks!
You mean something like this? (Demo):
$out = array();
foreach($input as $v)
{
$site_id = $v['site_id'];
unset($v['site_id']);
$out[$site_id][] = $v;
}
Or in case you prefer value pairs after each other (Demo):
...
unset($v['site_id']);
$out[$site_id][] = array_shift($v);
$out[$site_id][] = array_shift($v);
} ...

Counting unique arrays inside the array in PHP?

I have some array containing other arrays:
Array
(
[0] => Slip Object
(
[userId:protected] => 1
[parentSlipId:protected] => 0
[id:protected] => 25
[madeDatetime:protected] => 2011-04-19 17:13:09
[stake:protected] => 34.00
[status:protected] => 6
)
[1] => Slip Object
(
[userId:protected] => 1
[parentSlipId:protected] => 0
[id:protected] => 25
[madeDatetime:protected] => 2011-04-19 17:13:09
[stake:protected] => 34.00
[status:protected] => 6
)
[2] => Slip Object
(
[userId:protected] => 1
[parentSlipId:protected] => 0
[id:protected] => 24
[madeDatetime:protected] => 2011-04-18 11:31:26
[stake:protected] => 13.00
[status:protected] => 6
)
)
What's the best way of counting unique arrays?
Off the top of my head you could try:
$hashes = array();
$uniques = 0;
foreach($array as $slip) {
$hash = sha1(serialize($slip));
if(!in_array($hash, $hashes)) {
++$uniques;
$hashes[] = $hash;
}
}
var_dump($uniques); // prints total number of unique objects.
Edit:
#biakaveron's idea looks better though and could be adapted to:
$uniques = count(array_unique($array, SORT_REGULAR));
var_dump($uniques); // prints total number of unique objects.
This previous question has various solutions for removing duplicate arrays from within an array. If you implement any of them and then use sizeof() on the returned array you will have your solution.
eg:
<?php
$yourarray = array();
$tmp = array ();
foreach ($yourarray as $row)
if (!in_array($row,$tmp)) array_push($tmp,$row);
echo sizeof($tmp);
?>

Categories