I'm trying to repeat N times an array with a FOR loop, but I've been stuck in the last array that contains more elements. This is my code so far:
function data() {
for ($i = 1 ; $i <= 50 ; $i++) {
$magnitud = array('nombre' => 'medidor');
for ($j = 1 ; $j <= 5 ; $j++) {
$magnitude['magnitude'.$i] = array('date' => $date, 'value' => mt_rand(1,200));;
}
}
return $magnitude;
}
for ($i = 1 ; $i <= 50 ; $i++) {
$center->insertOne(['meter' => 'meter'.$i, 'data' => data()]);
}
I need to repeat 5 times the values of the array that contains the date and a value.
array('date' => $date, 'value' => mt_rand(1,200));
Something like this:
Date: 05/03/2015
Value: 25
Date: 10/12/2012
Value: 45
Date: 15/06/2005
Value: 67
Date: 26/05/2009
Value: 78
.
.
.
I've tried it in many ways, but I haven't acieved. Someone who lend me a hand to how to repeat N times that array?
Just in case you haven't got any idea about my question, I attach this picture wich is what I get in Robo3T (Visual Manager)
EDIT: To explain myself better, this is the json that I'm trying to get.
"_id" : ObjectId("5ab0c29db57dce17e0002bc0"),
"meter" : "meter1",
"data" : {
"magnitude1" : {
"date" : "20/10/2015 21:57:05",
"value" : 192,
"date" : "13/12/2015 22:51:15",
"value" : 85,
"date" : "15/05/2016 05:21:06",
"value" : 65,
"date" : "28/06/2017 15:32:26",
"value" : 72,
"date" : "02/11/2017 18:15:34",
"value" : 12,
},
"magnitude2" : {
"date" : "15/12/2009 15:21:32",
"value" : 45,
"date" : "12/05/2013 16:45:07",
"value" : 96,
"date" : "21/02/2015 03:06:12",
"value" : 85,
"date" : "15/08/2015 14:05:22",
"value" : 78,
"date" : "05/01/2017 21:12:32",
"value" : 198,
},
.
.
.
}
I think you mean you want to have 5 sub arrays of the magnitude array, so do it like this
function data() {
for ($i = 1 ; $i <= 50 ; $i++) {
for ($j = 1 ; $j <= 5 ; $j++) {
$magnitude['magnitude'.$i][] = array('date' => $date, 'value' => mt_rand(1,200));;
}
}
return $magnitude;
}
Not the use of [] in this line $magnitude['magnitude'.$i][] which will create a new sub occurrence within $magnitude['magnitude'.$i] each time round the inner loop
It is happening because the values are always overwrited as the key is never changed in the second loop. You can simplify it like this:
function data()
{
$value = 0;
for ($i = 0; $i < 250 ; $i++) {
$value = $i % 5 === 0 ? mt_rand(1, 200) : $value;
$magnitude['magnitude' . ($i + 1)] = array('date' => $date, 'value' => $value);
}
return $magnitude;
}
Related
I have a already defined array, containing values just like the one below:
$arr = ['a','b','c'];
How could one add the following using PHP?
$arr = [
'a' => 10,
'b' => 5,
'c' => 21
]
I have tried:
$arr['a'] = 10 but it throws the error: Undefined index: a
I am surely that I do a stupid mistake.. could someone open my eyes?
Full code below:
$finishes = []; //define array to hold finish types
foreach ($projectstages as $stage) {
if ($stage->finish_type) {
if(!in_array($stage->finish_type, $finishes)){
array_push($finishes, $stage->finish_type);
}
}
}
foreach ($projectunits as $unit) {
$data[$i] = [
'id' => $unit->id,
'project_name' => $unit->project_name,
'block_title' => $unit->block_title,
'unit' => $unit->unit,
'core' => $unit->core,
'floor' => $unit->floor,
'unit_type' => $unit->unit_type,
'tenure_type' => $unit->tenure_type,
'floors' => $unit->unit_floors,
'weelchair' => $unit->weelchair,
'dual_aspect' => $unit->dual_aspect
];
$st = array();
$bs = '';
foreach ($projectstages as $stage) {
$projectmeasure = ProjectMeasure::select('measure')
->where('project_id',$this->projectId)
->where('build_stage_id', $stage->id)
->where('unit_id', $unit->id)
->where('block_id', $unit->block_id)
->where('build_stage_type_id', $stage->build_stage_type_id)
->first();
$st += [
'BST-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure : '0')
];
if (($stage->is_square_meter == 0) && ($stage->is_draft == 0)) {
$height = ($stage->height_override == 0 ? $unit->gross_floor_height : $stage->height_override); //08.14.20: override default height if build stage type has it's own custom height
$st += [
'BST-sqm-'.$stage->build_stage_type_id => ($projectmeasure ? $projectmeasure->measure * $height: '0')
];
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure * $height: '0') * ($stage->both_side ? 2 : 1); //error is thrown at this line
}
} else {
if ($stage->finish_type) {
$finishes[$stage->finish_type] += ($projectmeasure ? $projectmeasure->measure : '0');
}
}
}
$data[$i] = array_merge($data[$i], $st);
$data[$i] = array_merge($data[$i], $finishes[$stage->finish_type]);
$i++;
}
The above code is used as is and the array $finishes is the one from the first example, called $arr
You're using += in your real code instead of =. That tries to do maths to add to an existing value, whereas = can just assign a new index with that value if it doesn't exist.
+= can't do maths to add a number to nothing. You need to check first if the index exists yet. If it doesn't exist, then assign it with an initial value. If it already exists with a value, then you can add the new value to the existing value.
If you want to convert the array of strings to a collection of keys (elements) and values (integers), you can try the following:
$arr = ['a','b','c'];
$newVals = [10, 5, 21];
function convertArr($arr, $newVals){
if(count($arr) == count($newVals)){
$len = count($arr);
for($i = 0; $i < $len; $i++){
$temp = $arr[$i];
$arr[$temp] = $newVals[$i];
unset($arr[$i]);
}
}
return $arr;
}
print_r(convertArr($arr, $newVals));
Output:
Array ( [a] => 10 [b] => 5 [c] => 21 )
I have a series of columns (Jan, Feb, Mar, etc) and I want to average the values of each column for each row however many there may be.
I have:
protected function generateAverage($staff, $type)
{
$months = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
$staff = array_map(function ($row) use ($type) {
if ($row['row_type'] == $type) {
return $row;
}
}, $staff);
foreach ($staff as $key => $employee) {
$months[0] += $employee['amounts'][0];
$months[1] += $employee['amounts'][1];
$months[2] += $employee['amounts'][2];
$months[3] += $employee['amounts'][3];
$months[4] += $employee['amounts'][4];
$months[5] += $employee['amounts'][5];
$months[6] += $employee['amounts'][6];
$months[7] += $employee['amounts'][7];
$months[8] += $employee['amounts'][8];
$months[9] += $employee['amounts'][9];
$months[10] += $employee['amounts'][10];
$months[11] += $employee['amounts'][11];
}
$months = array_map(function ($value) use ($staff) {
return $value / (count($staff) / 2);
}, $months);
$months[] = array_sum($months);
return $months;
}
Here is a sample of the data that goes into the above function:
array:6 [
0 => array:4 [
"amounts" => array:13 [
0 => "30000.00"
1 => "30000.00"
2 => "30000.00"
3 => "30000.00"
4 => "30000.00"
5 => "30000.00"
6 => "30000.00"
7 => "30000.00"
8 => "30000.00"
9 => "30000.00"
10 => "30000.00"
11 => "30000.00"
12 => 360000.0
]
"image" => "test.jpg"
"row_name" => "Target"
"row_type" => "target"
]
...
Usage:
$data['aggregates']['Target average'] = $this->generateAverage(array_values($data['staff']), 'target');
I feel the way the average is calculated is messy, is there a better way to do this?
A couple of small footprint reductions
protected function generateAverage($staff, $type)
{
// create 12 months with 0 value
$months = array_fill(0, 12, 0);
// use array_filter instead of map
$staff = array_filter(function ($row) use ($type) {
return $row['row_type'] === $type;
}, $staff);
// do count outside loop
$staffCount = count($staff);
// loop employees and add up each month, dividing early
foreach ($staff as $employee) {
for ($i = 0; $i < 12; $i++) {
$months[$i] += $employee['amounts'][$i] / $staffCount;
}
}
return $months;
}
I dont know why you are dividing the staff count by 2 or why you are summing in the end, my function just gives an average per month.
Since you're using Laravel, most of the data you work with is collections. So, before converting a collection into an array, you could use avg() helper:
$collection->avg($key);
I think you can consider using array_colum,
1) array_column makes an array of all the values in a particular index position in a row
$column1 = array_column($employee, 0 );
$column2 = array_column($employee, 1 );
$column3 = array_column($employee, 2 );
.
.
.
2)Get the column count by count($columnX), where X is the index of the column
3) Using (1) and (2) calculate the average as needed
I need a proper JSON file with "geo_langitude", "geo_latitude", "adress" & "url" values
I have wp database with post_meta "property" - "geo_langitude" "geo_latitude" & "address" in there.
my file is smth like that
<?php
function return_markers($count) {
$query = new WP_Query('post_type=property&posts_per_page=-1&orderby=menu_order&order=DESC&post_status=publish');
$array = array();
$i = 0;
for ($i = 0; $i< $count; $i++) {
$elem = array(
't' => 'string '.$i,
'x' => get_post_meta($post->ID,'geo_latitude',true),
'y' => get_post_meta($post->ID,'geo_longitude',true),
'z' => $i
);
$array[] = $elem;
}
echo json_encode($elem);
};
return_markers($i);
?>
It's my first time using JSON so I have troubles and I don't know where. =(
with random markers work perfectly:
<?php
function return_markers($count) {
$array = array ();
for ($i = 0; $i< $count; $i++) {
$elem = array(
't' => 'string '.$i,
'x' => 23 + (rand ( 0 , 10000 ) / 10000) * 5,
'y' => 56.2 + (rand ( 0 , 10000 ) / 10000) * 0.8,
'url' => '#map_redirect_'.$i,
'z' => $i
);
$array[] = $elem;
}
echo json_encode($array);
};
return_markers(23);
?>
For example, I have inserted 10K documents in collection:
for ($i = 0; $i < 100; ++$i) {
for ($j = 0; $j < 100; ++$j) {
$collection->insert(array('i' => $i, 'j' => $j));
}
}
I have created Indexes:
pkrs:PRIMARY> db.testTest.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "parts.testTest",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"i" : 1,
"j" : 1
},
"ns" : "parts.testTest",
"name" : "i_1_j_1"
}
]
Then I want to fetch 600 documents with 'OR' condition:
for ($i = 5; $i < 12; ++$i) {
for ($j = 0; $j < 100; ++$j) {
$orArr[] = array('i'=>$i, 'j' => $j);
}
}
$cursor = $collection->find(array('$or' => $orArr));
$cursor->batchSize(1000);
foreach ($cursor as $doc) {
// code
}
And first document fetches about 1.5 second! :(
How can I improve performance?
I have the following structure of data in an array and I am trying to calculate the total duration:
$elements = array(
'elementfrom-work' => "09:00",
'elementto-work' => "17:00",
'elementdays-work' => "5",
'elementfrom-karate' => "18:00",
'elementto-karate' => "20:00",
'elementdays-karate' => "3",
'elementfrom-stamp' => "21:00",
'elementto-stamp' => "22:00",
//it doest have the default days 'elementdays-stamp' set
//so it will take the default 7
'element-simple1' => "4", //it will take the default 7
'element-simple2' => "8", //it will take the default 7
'element-simple3' => "1",
'elementdays-simple3' => "1", //day is set
);
I have managed to do it but my code is messy, for each item it gets the sub string and runs another for loop to check if any other elements exists when it is not simple (like days) .
I am trying to calculate for each item the total duration e.g outcome is:
Work:40
Karate:6
Stamp:7
Simple1=28
Simple2=56
Simple3=1
total duration:138
Can this be done without two for loops and how ? If it is not possible how would you calculate it.
I actually found this problem quite interesting, so you can do something like:
$elements[] = array(
'elementfrom-work' => "09:00",
'elementto-work' => "17:00",
'elementdays-work' => "7",
'elementfrom-karate' => "18:00",
'elementto-karate' => "20:00",
'elementdays-karate' => "3",
'elementfrom-stamp' => "21:00",
'elementto-stamp' => "22:00",
'a' => "21:00",
'b' => "22:00"
);
And use those two functions:
function negative($x)
{
if($x < 0)
{
return -$x;
}
return $x;
}
function isTime($string)
{
$split = explode(":", $string);
if(isset($split[1]))
{
return true;
}
return false;
}
foreach($elements as $key => $val)
{
$total = 0;
$temp = 0;
$i = 0;
foreach($val as $innerKey => $time)
{
$isTime = isTime($time);
$split = explode(":", $time);
$h = $split[0];
switch($i)
{
case 0:
$temp -= $h;
break;
case 1:
$temp += $h;
break;
case 2:
if($isTime)
{
$mult = $temp *= 7;
$unsigned = negative($mult);
$total += $unsigned;
$temp = 0;
$temp -= $h;
$i = 0;
break;
}
$mult = $temp *= $h;
$unsigned = negative($mult);
$total += $unsigned;
$temp = 0;
$i = -1;
break;
default:
break;
}
$i++;
}
echo $total;
}
Your idea of the carry is a bit funky but something like that should work.
It looks like you know the expected name of the days item... check if it's exists instead of looping, iterate the array keys, when you get to "elementfrom-work" you can check if array got key "elementdays-work" instead of re iterate to search this item in N level complexity...