I hope you could help me on how should I make this output be done.
CSV file
Department,Name,Employee No.,Date Time
LMS,"Bach, Jerome",102,6/30/2014 12:23
MTS,"Lorvia, Christine",103,6/16/2014 9:31
SSS,Jannah Curtis,104,6/16/2014 8:45
SSS,Jannah Curtis,104,6/28/2014 14:29
ITM,Sassy Mica,105,6/17/2014 9:12
ITM,Sassy Mica,105,6/17/2014 20:43
ITM,Sassy Mica,105,6/18/2014 9:12
I already grouped the department and this is the output
[MTS] => Array
(
[103] => Array
(
[0] => MTS
[1] => Lorvia Christine
[2] => 103
[3] => 6/16/2014 9:31
)
)
[SSS] => Array
(
[104] => Array
(
[0] => SSS
[1] => Jannah Curtis
[2] => 104
[3] => 6/28/2014 14:29
)
)
[ITM] => Array
(
[105] => Array
(
[0] => ITM
[1] => Sassy Mica
[2] => 105
[3] => 6/18/2014 9:12
)
)
but I want an output that will result all her date/time record under the element [3].
Ex.
[ITM] => Array
(
[105] => Array
(
[0] => ITM
[1] => Sassy Mica
[2] => 105
[3] => 6/17/2014 9:12
=> 6/17/2014 20:43
=> 6/18/2014 9:12
)
)
While the time record is sorted.
You don't have a choice. You need to process them accordingly. The array format you desire is invalid, since they cannot share the same key, just create another dimension for the time. Example:
$data = array();
$handle = fopen('sample.csv', 'r');
while(!feof($handle)) {
$row = fgetcsv($handle, '4096');
if(!isset($data[$row[0]][$row[2]])) {
// simple assignment
$data[$row[0]][$row[2]] = array($row[0], $row[1], $row[2], array($row[3],));
} else {
// process
$data[$row[0]][$row[2]][3][] = $row[3]; // push it inside instead of assigning a new one
$temp = $data[$row[0]][$row[2]][3]; // temporary storage
$temp = array_map(function($var){
return strtotime($var); // convert to unix time
}, $temp);
sort($temp); // sort ascending
$data[$row[0]][$row[2]][3] = array_map(function($var){
return date('m/d/Y H:i', $var); // return to old format with sorted values
}, $temp);
}
}
array_shift($data); // remove the first (the header)
echo '<pre>';
print_r($data);
Should yield something like:
Array
(
[LMS] => Array
(
[102] => Array
(
[0] => LMS
[1] => Bach, Jerome
[2] => 102
[3] => Array
(
[0] => 6/30/2014 12:23
)
)
)
[MTS] => Array
(
[103] => Array
(
[0] => MTS
[1] => Lorvia, Christine
[2] => 103
[3] => Array
(
[0] => 6/16/2014 9:31
)
)
)
[SSS] => Array
(
[104] => Array
(
[0] => SSS
[1] => Jannah Curtis
[2] => 104
[3] => Array
(
[0] => 06/16/2014 08:45
[1] => 06/28/2014 14:29
)
)
)
[ITM] => Array
(
[105] => Array
(
[0] => ITM
[1] => Sassy Mica
[2] => 105
[3] => Array
(
[0] => 06/17/2014 09:12
[1] => 06/17/2014 20:43
[2] => 06/18/2014 09:12
)
)
)
)
Related
I would like to switch from array 1 to array 2 according to the model below
I'm stuck on the implementation of item averages
the lessons, the number of notes and the order of the notes are random
Array 1
$tabAsso =
Array
(
[51] => Array
(
[id] => 51
[name] => JOHN
[studies] => Array
(
[0] => math
[1] => LV1
[2] => math
[3] => LV1
[4] => history
[5] => history
)
[notesC] => Array
(
[0] => 12
[1] => 18
[2] => 28
[3] => 45
[4] => 10
[5] => 18
)
[denumsC] => Array
(
[0] => 15
[1] => 60
[2] => 40
[3] => 75
[4] => 12
[5] => 45
)
)
[52] => Array
(
[id] => 52
[name] => PETER
[studies] => Array
(
[0] => sport
[1] => tech
[2] => sport
...
For example for the math average, you must read :
notesC:
sum (12 + 28)
denumC
sum (15 +40)
then average : (40/55) *20 = 14.5
I would like to reach this array 2
[51] => Array
(
[id] => 51
[name] => JOHN
[studies] => Array
(
[0] => math
[1] => LV1
[2] => history
)
[averages] => Array
(
[0] => 14.5
[1] => 9.3
[2] => 9.8
)
)
[52] => Array
(
[id] => 52
[name] => PETER
[studies] => Array
(
[0] => sport
[1] => tech
)
[averages] => Array
(
[0] => xx
[1] => xx
)
)
...
So far I have managed to do this ...
$tabAssoForBar = [];
foreach ($tabAsso as $id => $t) {
foreach ($t['studies'] as $k => $m) {
if (!array_key_exists($id, $tabAssoForBar)) {
$tabAssoForBar[$id] = [
'id' => $id,
'name' => $t['name'],
];
$tabAssoForBar[$id]['studies'] = [$m];
} else {
if (!in_array($m, $tabAssoForBar[$id]['studies'])) {
$tabAssoForBar[$id]['studies'][] = $m;
} else {
// nothing
}
}
}
};
I return studies with only 3 fields (math, LV1, history) but cannot create the averages field
Thanks for your help
You might use an approach to get all the indices from
"study" for a all the unique values, and get the values from "notesC" and "denumsC" for those corresponding indices.
Then per unique value for "study", first sum them separately for "notesC" and "denumsC" and then divide those results and multiply the outcome by 20 to fulfill this formula:
(40/55) *20 = 14.5
You can create the result array by using the current index as the index in the new array and the unique studies and averages to it.
For example
$tabAssoForBar = [];
foreach ($tabAsso as $id => $t) {
$uniqueStudies = array_unique($t['studies']);
$averages = [];
foreach ($uniqueStudies as $uniqueStudy) {
$keysFromStudies = array_keys(array_filter($t['studies'], function($x) use ($uniqueStudy) {
return $x === $uniqueStudy;
}));
$averages[] = round(
(
array_sum(array_intersect_key($t['notesC'], array_flip($keysFromStudies))) /
array_sum(array_intersect_key($t['denumsC'], array_flip($keysFromStudies)))
) * 20,
1
);
}
$tabAssoForBar[$id] = [
'id' => $t['id'],
'name' => $t['name'],
'studies' => array_values($uniqueStudies),
'averages' => $averages
];
}
print_r($tabAssoForBar);
Output
Array
(
[51] => Array
(
[id] => 51
[name] => JOHN
[studies] => Array
(
[0] => math
[1] => LV1
[2] => history
)
[averages] => Array
(
[0] => 14.5
[1] => 9.3
[2] => 9.8
)
)
)
See a php demo
I've a muti dimensional array. I want to concatenate 2 strings separately for 2 array values and the 2 strings should not be concatenated for a single value. I want CM and PM concatenated 2 times any where in the array. I've tried looping the array and generating array_rand but i generates only once. Any help is much appreciated. Below is one example of what am achieving.
Thing am trying to achieve
Concatenate "PM" and "CM" string in one set of array and same value can't be CM and PM
Every array should have PM and CM concatenated
1 "Name" value should have minimum 1 CM and PM and Maximum 2 CM and PM
For example: I've the below multi dimensional array.
Array
(
[0] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[1] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[2] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[3] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[4] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
)
After concatenating
Array
(
[0] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C["PM"]
[3] => Name-4["CM"]
[4] => Name-5
)
[1] => Array
(
[0] => Name-A
[1] => Name-B["PM"]
[2] => Name-C
[3] => Name-4["CM"]
[4] => Name-5
)
[2] => Array
(
[0] => Name-A["PM"]
[1] => Name-B
[2] => Name-C
[3] => Name-4
[4] => Name-5["CM"]
)
[3] => Array
(
[0] => Name-A["PM"]
[1] => Name-B["CM"]
[2] => Name-C
[3] => Name-4
[4] => Name-5
)
[4] => Array
(
[0] => Name-A
[1] => Name-B
[2] => Name-C["CM"]
[3] => Name-4
[4] => Name-5["PM"]
)
)
Sorry I didn't understand at first.
Given $your_array:
// Generate an array where the names are the key, and assign a zero value to PM (0) and CM (1) in a sub array
$ar = array_fill_keys($your_array[0], array (0 => 0, 1 => 0));
//$array the sub_value, $add the case PM ou CM, $exclusion is the key used the first time
function rand_in_array($array, $add, $ar, $exclusion)
{
// Select a random key
$arr_key = array_rand($array, 1);
if($ar[$array[$arr_key]][$add] < 2 && ($arr_key != $exclusion))
{
return $arr_key;
}
return rand_in_array($array, $add, $ar, $exclusion);
}
for($i=0; $i<count($your_array);$i++)
{
$arr_key_pm = rand_in_array($your_array[$i], 0, $ar, 99);
$ar[$your_array[$i][$arr_key_pm]][0]++;
$arr_key_cm = rand_in_array($your_array[$i], 1, $ar, $arr_key_pm);
$ar[$your_array[$i][$arr_key_cm]][1]++;
$your_array[$i][$arr_key_pm] .= "PM";
$your_array[$i][$arr_key_cm] .= "CM";
}
It is ugly but it works :)
Somewhere should existe someone able to make more aesthetic..
for($i=0; $i<count($your_array);$i++)
{
$arr_keys = array_rand($your_array[$i], 2);
$your_array[$i][$arr_keys[0]] .= "PM";
$your_array[$i][$arr_keys[1]] .= "CM";
}
Should do the work.
I assume your inner array index is starting from zero. So generate the random index between 0 to your ( inner_array_size - 1). Then assign the value in the array's reference variable withing the loop.
foreach ($arr as &$value) {
$randomIndex = array_rand(range(0, (count($value) -1) ), 2);
$value[$randomIndex[0]] .= ' ["CM"]';
$value[$randomIndex[1]] .= ' ["PM"]';
}
I have two arrays that was converted from csv file.
The first csv line looks like this:
franchise_id,franchise_name,phone,website,email,region_codes;
1,"Abbott, Hackett and O`Conner",1-648-177-9510,auto-service.co/bw-319-x,Lupe-2485#auto-service.co,"36101,36055,36071";
The second csv line looks like this:
postal_code,region_code,city,state,region;
14410,36055,Adams Basin,NY,Monroe;
I converted these lines to arrays like this:
//Region Array
$region_lines = explode(PHP_EOL, $region_mappings_string);
$region_array = array();
foreach ($region_lines as $region_line) {
$region_array[] = str_getcsv($region_line);
}
//Franchise Array
$franchise_lines = explode(PHP_EOL, $franchises_string);
$franchise_array = array();
foreach ($franchise_lines as $franchise_line) {
$franchise_array[] = str_getcsv($franchise_line);
}
After that I got the result like this for Region:
Array
(
[0] => Array
(
[0] => postal_code
[1] => region_code
[2] => city
[3] => state
[4] => region;
)
[111] => Array
(
[0] => 14410
[1] => 36055
[2] => Adams Basin
[3] => NY
[4] => Monroe;
)
[112] => Array
(
[0] => 14617
[1] => 36055
[2] => Rochester
[3] => NY
[4] => Monroe;
)
And for franchise:
Array
(
[0] => Array
(
[0] => franchise_id
[1] => franchise_name
[2] => phone
[3] => website
[4] => email
[5] => region_codes;
)
[1] => Array
(
[0] => 1
[1] => Abbott, Hackett and O`Conner
[2] => 1-648-177-9510
[3] => auto-service.co/bw-319-x
[4] => Lupe-2485#auto-service.co
[5] => 36101,36055,36071;
)
What I need to do is to look for 14410 postal code from the first array, get the region_code and look for this region_code in second array and then output the results in PHP. How can this be done?
Will have to loop over franchises array and run simple comparison
function getDataByRegionCode($code, $franchiseArray) {
foreach ($franchiseArray as $key => $data) {
if(isset($data[5])){
$codes = explode(',',$data[5]);
if(in_array($code,$codes)) return $data;
}
}
return NULL;
}
print_r(getDataByRegionCode(14410,$franchiseArray));
I stuck on this and really don't know how to solve it.
I have two multi-dimensional arrays and need to match every "entry_id" from second array with first one. Then need to check if every "file_no" from second array is in database (first array) and "status" are matched with 1st array . If "status" is different, update second array with string (e.g. updated value) like this:
...
[status] => Array
(
[0] => abc
[1] => defghijk - "updated value"
)
So I have first array from database:
Array
(
[0] => Array
(
[entry_id] => 1
[file_no] => KSBR 40 INS 3674 / 2014
[status] => abc
)
[1] => Array
(
[entry_id] => 9
[file_no] => KSUL 77 INS 18898 / 2013
[status] => abc
)
[2] => Array
(
[entry_id] => 9
[file_no] => KSUL 77 INS 21218 / 2013
[status] => defg
)
)
And second array generated from script:
Array
(
[0] => Array
(
[entry_id] => 1
[id] => 500910/098
[fullname] => Milan Vrtal
[type] => person
[file_no] => Array
(
[0] => KSBR 26 INS 37146 / 2013
[1] => KSBR 40 INS 3674 / 2014
)
[status] => Array
(
[0] => status1
[1] => status2
)
)
[1] => Array
(
[entry_id] => 2
[id] => 46900217
[fullname] => ENTEC a.s.
[type] => company
[file_no] => Array
(
[0] => KSBR 28 INS 1232 / 2013
)
[status] => Array
(
[0] => qwer
)
)
[2] => Array
(
[entry_id] => 9
[fullname] => Blanka Kořínková
[type] => person
[file_no] => Array
(
[0] => KSUL 77 INS 18898 / 2013
[1] => KSUL 77 INS 21218 / 2013
)
[status] => Array
(
[0] => abc
[1] => defghijk
)
)
)
Thanks for every comment and sorry for english :)
This is by creating a temporary array to search in. This will use quite some memory when the arrays are big, but will result in faster execution time...
$tmparr = array();
foreach($arr1 as $arr1_val)
{
//put an new element in $temparr with key 'entry_id' and an array as value
if (!isset($tmparr[$arr1_val['entry_id']]))
$tmparr[$arr1_val['entry_id']] = array();
//add the status to the array
$tmparr[$arr1_val['entry_id']][] = $arr1_val['status'];
}
/*
$tmparr = Array
(
[1] => Array
(
[0] => abc
)
[9] => Array
(
[0] => abc
[1] => defg
)
)
*/
//arr2_val by reference so that we can change it
foreach($arr2 as &$arr2_val)
{
//get the current entry_id
$entry_id = $arr2_val['entry_id'];
//see if this entry_id was in the first array, and if so...
if (isset($tmparr[$entry_id]))
{
//change the status to both the original status and the status of the first array
$arr2_val['status'] = array_merge($arr2_val['status'],$tmparr[$entry_id]);
}
}
print_r($arr2);
Output:
Array
(
[0] => Array
(
[entry_id] => 1
[id] => 500910/098
[fullname] => Milan Vrtal
[type] => person
[file_no] => Array
(
[0] => KSBR 26 INS 37146 / 2013
[1] => KSBR 40 INS 3674 / 2014
)
[status] => Array
(
[0] => status1
[1] => status2
[2] => abc
)
)
[1] => Array
(
[entry_id] => 2
[id] => 46900217
[fullname] => ENTEC a.s.
[type] => company
[file_no] => Array
(
[0] => KSBR 28 INS 1232 / 2013
)
[status] => Array
(
[0] => qwer
)
)
[2] => Array
(
[entry_id] => 9
[fullname] => Blanka Kořínková
[type] => person
[file_no] => Array
(
[0] => KSUL 77 INS 18898 / 2013
[1] => KSUL 77 INS 21218 / 2013
)
[status] => Array
(
[0] => abc
[1] => defghijk
[2] => abc
[3] => defg
)
)
)
edit: This is possible too, whitout the temp array, but with a loop in a loop. This will be slower than the first one, but will consume less memory:
//arr2_val by reference so that we can change it
foreach($arr2 as &$arr2_val)
{
//get the current entry_id
$entry_id = $arr2_val['entry_id'];
//search for the correct row in the first array
foreach($arr1 as $arr1_val)
{
if ($arr1_val['entry_id'] == $arr2_val['entry_id'])
{
$arr2_val['status'][] = $arr1_val['status'];
//a continue should be added here to make it faster...
}
}
}
print_r($arr2);
This should work
foreach($array1 as $i)
{
foreach($array2 as $key=>$j)
{
if($j['entry_id'] == $i['entry_id'])
{
if($array2[$key]['status'] != $i['status'])
{
$j['status'] = array(
$i['status'],
$j['status'] // the new status
);
}
continue;
}
}
}
I found a solution for you :
$a1 = [['entry_id' => 1, 'file_no' => 'KSBR', 'status' => 'abc'], ['entry_id' => 2, 'file_no' => 'KSUL', 'status' => 'defg']];
$a2 = [['entry_id' => 1, 'file_no' => 'KSBR', 'status' => 'abc', 'type' => 'person'], ['entry_id' => 2, 'file_no' => 'KSUL', 'status' => 'defg']];
print_r(new_array_merge_recursive($a1, $a2));
function new_array_merge_recursive(array $array1, array $array2=array())
{
$arrays = func_get_args();
$merge = array_shift($arrays);
foreach ($arrays as $array)
{
foreach ($array as $key => $val)
{
if (is_array($val) && array_key_exists($key, $merge))
{
$val = new_array_merge_recursive((array) $merge[$key], $val);
}
$merge[$key] = $val;
}
}
return $merge;
}
i have created a function in php to convert an string like:
[20110911, 20110913, [20110915, 20110918], 20110920, 20110922, 20110924, [20110926, 20110927], 20110929]
to php array like:
Array
(
[0] => 20110911
[1] => 20110913
[2] => Array
(
[0] => 20110915
[1] => 20110918
)
[3] => 20110920
[4] => 20110922
[5] => 20110924
[6] => Array
(
[0] => 20110926
[1] => 20110927
)
[7] => 20110929
[8] => Array
(
[0] => 20111001
[1] => 20111002
)
[9] => 20111004
[10] => Array
(
[0] => 20111006
[1] => 20111007
)
)
The function is:
function dates2Array($d){
if($d!==''){
$d=substr($d, 1, strlen($d)-2);
$d=explode(', ', $d);
$dates=array();
if(!empty($d)){
$j=1;
foreach($d as $k=>$v){
if(substr($v, 0, 1)==='[') $dates[]=array(substr($v, 1, strlen($v)));
elseif(substr($v, strlen($v)-1, strlen($v))===']'){
$dates[$k-$j][1]=substr($v, 0, strlen($v)-1);
$j++;
}
else $dates[]=$v;
}
}
}
return $d!==''?$dates:'';
}
I am not fully happy with my function.
I think it can be more optimized and compressed for speed..
Can it be?
Use JSON (json_decode() and json_encode()) instead
http://sandbox.phpcode.eu/g/b3814/2
result:
Array
(
[0] => 20110911
[1] => 20110913
[2] => Array
(
[0] => 20110915
[1] => 20110918
)
[3] => 20110920
[4] => 20110922
[5] => 20110924
[6] => Array
(
[0] => 20110926
[1] => 20110927
)
[7] => 20110929
)
You can pass your string in {...} and pass it to json_decode(str, true) to get back an array.
>> json_decode("[20110911, 20110913, [20110915, 20110918], 20110920, 20110922, 2
0110924, [20110926, 20110927], 20110929]")
array (
0 => 20110911,
1 => 20110913,
2 =>
array (
0 => 20110915,
1 => 20110918,
),
3 => 20110920,
4 => 20110922,
5 => 20110924,
6 =>
array (
0 => 20110926,
1 => 20110927,
),
7 => 20110929,
)