Reading a file line by line and extract values - php

I need to do a routine that is able to extract values from a file and send these values to a mySQL database.
However my routine is returning some, imo, odd results.
This is my code:
$file = new SplFileObject($file_name);
for($i = 1 ; $i <= 5 ; $i++)
//while (!$file->eof())
{
$linha = $file->fgets();
echo $linha.'<br>';
$line = explode(" ", $linha);
print_r($line);
echo '<br'>;
}
$file = null;
I used to have a while loop to run the whole file, but was getting an error and then decided to do a for loop to have a smaller number of results.
The results I get are:
1 1412114400 100 20 10 2 1 80 15 8 1.5 true 20 5
Array ( [0] => 1 [1] => 1412114400 [2] => 100 [3] => 20 [4] => 10 [5] => 2 [6] => 1 [7] => 80 [8] => 15 [9] => 8 [10] => 1.5 [11] => true [12] => 20 [13] => 5 )
Array ( [0] => )
2 1412114460 100 20 10 2 1 80 15 8 1.5 true 20 5
Array ( [0] => 2 [1] => 1412114460 [2] => 100 [3] => 20 [4] => 10 [5] => 2 [6] => 1 [7] => 80 [8] => 15 [9] => 8 [10] => 1.5 [11] => true [12] => 20 [13] => 5 )
Array ( [0] => )
3 1412114520 100 20 10 2 1 80 15 8 1.5 true 20 5
Array ( [0] => 3 [1] => 1412114520 [2] => 100 [3] => 20 [4] => 10 [5] => 2 [6] => 1 [7] => 80 [8] => 15 [9] => 8 [10] => 1.5 [11] => true [12] => 20 [13] => 5 )
It seems that for every other cicle the fgets() function returns a "\n\r" and I don't know how to get rid of it.
EDIT:
I've used trim() and str_replace() and got the same result, so maybe I'm not getting a "\n\r".

<?php
$file = new SplFileObject($file_name);
$i = 1;
while ($i <= 5) {
$linha = trim($file->fgets());
if ($linha == '') {
continue;
}
echo $linha.'<br>';
$line = explode(" ", $linha);
print_r($line);
echo '<br>';
$i++;
}
$file = null;

to get rid of \r\n use:
$line = str_replace(array("\r", "\n", "\r\n"), array('', '', ''), $line);
I would also recommend using file_get_contents() as it offers a much cleaner way of reading files: http://php.net/manual/en/function.file-get-contents.php
You are also missing a > off your second <br>

Related

Function to separate and write dataset in chunks of n does not work. Tried array_slice and for-loop

I am trying to separate and write chunks of n datapoints recursively from the first to n.
e.g. I want the first 20, then the next 20 (starting from the second point), and so on. From 1 to 20 (in a dataset of 40 points).
It seems to work at the beginning then the last chunks are offset by 1 point. I'm sure it has to be the most obvious error but I just can't wrap my head around it!!!
I've tried array_slice() and a for() loop. Both give me the same error.
function array_smas($series, $length){ # Uses array_slice()
for($i = 0; $i < $length; $i++){
echo "i = $i\n";
$offset = $length - $i - 1;
echo "offset = $offset\n";
$series_n = array_slice($series, $offset, $length);
file_put_contents(__DIR__."/file.txt", print_r($series_n, true), FILE_APPEND);
file_put_contents(__DIR__."/file.txt", "\n\n", FILE_APPEND);
}
return 0;
}
function array_smas_forloop($series, $length){ # Uses for-loop
for($i = 0; $i < $length; $i++){
echo "i = $i\n";
$series_n = array();
for($c = 0; $c < $length; $c++){
$series_n[] = $series[$c + $i];
}
file_put_contents(__DIR__."/file.txt", print_r($series_n, true), FILE_APPEND);
file_put_contents(__DIR__."/file.txt", "\n\n", FILE_APPEND);
}
return 0;
}
Using a dataset of 40 points, the first and last arrays and $i outputs should be:
i = 0
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
[8] => 9
[9] => 10
[10] => 11
[11] => 12
[12] => 13
[13] => 14
[14] => 15
[15] => 16
[16] => 17
[17] => 18
[18] => 19
[19] => 20
)
...
i = 18
Array
(
[0] => 20
[1] => 21
[2] => 22
[3] => 23
[4] => 24
[5] => 25
[6] => 26
[7] => 27
[8] => 28
[9] => 29
[10] => 30
[11] => 31
[12] => 32
[13] => 33
[14] => 34
[15] => 35
[16] => 36
[17] => 37
[18] => 38
[19] => 39
)
i = 19
Array
(
[0] => 21
[1] => 22
[2] => 23
[3] => 24
[4] => 25
[5] => 26
[6] => 27
[7] => 28
[8] => 29
[9] => 30
[10] => 31
[11] => 32
[12] => 33
[13] => 34
[14] => 35
[15] => 36
[16] => 37
[17] => 38
[18] => 39
[19] => 40
)
The problem seems to be that you can't have $i = 19 and the first element as 21. My logic is that if you look at the first loop where $i = 0, the first element is 1 - so 1 difference. BUT when it's 19, you want the first element to be 21 - 2 higher than this number.
If in your array_smas_forloop() you change the limit of the loop to...
for($i = 0; $i <= $length; $i++){
then you should get the desired output.
BUT, there is a lot of array creating and file opening and closing going on. Another alternative is to create a 'window' on the array, remove the first item each time and add a new one to the end. Also to open the file at the start of the function and close it at the end...
function array_smas_window($series, $length){ // Using for 'window'
$output = fopen(__DIR__."/file.txt", "w");
$window = array_slice($series, 0, $length);
$i = 0;
while(true) {
fwrite($output, print_r($window, true)."\n\n");
// If there are no more items, break the loop
if ( !isset($series[$length+$i]) ) {
break;
}
// Remove the first item
array_shift($window);
// Add a new one to the end
$window[] = $series[$length+$i++];
}
fclose($output);
}
This should also work for any window size as it carries on till there are no more items to add on.

how to search array by specifying the index to start search from in php

how to search array by specifying the index to start search from in php
for example:
Assuming
$needle_to_search = 5;
$array_to_search = [6,8,4,9,7,5,9,4,5,9,3,5,4,6,7];
$index_to_start_search_from = 5;
$key = array_search($needle_to_search, $array_to_search, $index_to_start_search_from);
is there any function that can implement above pseudo code
so that $key will return index: 8
what i mean is that i want to start the search from index 6 so that it returns index 8=> which has the value 5, since value 5 is my aim to search in the array.
i think you can do with array_slice.
$needle_to_search = 5;
$array_to_search = [6,8,4,9,7,5,9,4,5,9,3,5,4,6,7];
$index_to_start_search_from = 6;
// output
Array
(
[0] => 6
[1] => 8
[2] => 4
[3] => 9
[4] => 7
[5] => 5
[6] => 9
[7] => 4
[8] => 5
[9] => 9
[10] => 3
[11] => 5
[12] => 4
[13] => 6
[14] => 7
)
// return 5
echo array_search($needle_to_search, $array_to_search);
// return 8
echo array_search($needle_to_search, array_slice($array_to_search, $index_to_start_search_from, null, true));

How to create a looping random number generator

I need to create a looping random number generator so each loops pumps out a different set of random numbers.
e.g result would be:
9463216549
6541335466
6749746326
6546879994
Code I have so far is:
<?php
$limit1 = 10;
$counter1 = 1;
$limit2 = 4;
$counter2 = 1;
while ($counter2 <= $limit2) {
while ($counter1 <= $limit1) {
$rayndom = mt_rand(0,6);
$counter1++;
}
$counter2++;
}
?>
If you are using php version > 7 you can use inbuilt function random_int():
Generates cryptographically secure pseudo-random integers
Usage of random_int():
random_int(0, 1000); // 0 is min value and 1000 is max
random_int() is always safe alternative to rand() and mt_rand()
If you are using PHP version < 7.0 then you can take a look at userland implementation of random_int i.e. random_compat.
Here is the code hope this helps
<?php
$waves = array(
array(),
array(),
array(),
array()
);
foreach($waves as $wave) {
for($counter = 1; $counter <= 10; $counter++) {
$num = mt_rand(0,6);
array_push($wave, $num);
}
print_r($wave);
}
?>
Your array will look like this
Array
(
[0] => 0
[1] => 2
[2] => 1
[3] => 0
[4] => 2
[5] => 1
[6] => 2
[7] => 6
[8] => 5
[9] => 0
)
Array
(
[0] => 4
[1] => 2
[2] => 2
[3] => 5
[4] => 5
[5] => 5
[6] => 6
[7] => 0
[8] => 4
[9] => 2
)
Array
(
[0] => 5
[1] => 4
[2] => 2
[3] => 5
[4] => 4
[5] => 3
[6] => 0
[7] => 3
[8] => 5
[9] => 2
)
Array
(
[0] => 2
[1] => 1
[2] => 4
[3] => 5
[4] => 0
[5] => 2
[6] => 4
[7] => 4
[8] => 4
[9] => 6
)
each array will be one wave

How to find available batches inside of number range in php

There is a problem that I'm spending some time to figure out a solution.
There is a main number batch. For example 100 - 150(size - 51).
And also there are few sub batches inside of that main batch. For example 105 - 110 and 120 - 130.
I want to get other batches and their batch sizes inside of main batch.
For example
100-104, 111-119 and 131-150
I have tried to find a solution for this but haven't found any solution yet. Is there anyone who can guide me to do this in php or give pseudocode, it will be very helpful for me.
Thanks
Using array_diff, you can find the free spaces in your array of batches.
Then extract from this list the parts without interruption of keys, resulting in each free ranges left.
$mainBatch = range(100, 150);
$subBatch = range(110, 120);
$subBatch2 = range(130,145);
$subBatchesFree = array_diff($mainBatch, $subBatch, $subBatch2);
$remainingBatches = array();
$i = 0;
foreach ($subBatchesFree as $key => $available) {
if (isset($subBatchesFree[$key + 1])) {
// Next key is still in the range
++$i;
} else {
// Next key is in a new range.
// I create the current one and init for the next range
$remainingBatches[] = range($subBatchesFree[$key - $i], $available);
$i = 0;
}
}
print_r($remainingBatches);
Output :
Array
(
[0] => Array
(
[0] => 100
[1] => 101
[2] => 102
[3] => 103
[4] => 104
[5] => 105
[6] => 106
[7] => 107
[8] => 108
[9] => 109
)
[1] => Array
(
[0] => 121
[1] => 122
[2] => 123
[3] => 124
[4] => 125
[5] => 126
[6] => 127
[7] => 128
[8] => 129
)
[2] => Array
(
[0] => 146
[1] => 147
[2] => 148
[3] => 149
[4] => 150
)
)

2 arrays count how many times id = date

Ive sat with this for a while now, and its getting late.
Im trying to get a top 3 of most sales from last month, and i need to count how many times a id from array 1 is equal to array 2 last month(6 = last atm.) like id 4 = 2, id 7 = 3
It might not be the perfect solution, but im just trying to break it down by my self, so later on 'maybe' problems, will i take care of when i hit the wall,
so please, if anyone can help me here, ill be greatfull.
UPDATE
- I will add the result im looking for here: (sorry i didnt before, it makes it alot easier :-)
- The result below, is because i want the count from 2014-06-01 and up to the last day of that month monly, on array[0][1] under this array, only 6-7-8 is not from 2014-06
Hope it makes a bit more sense now ^^
Array
(
[0] => Array
(
[0] => Array
(
[4] => 2
[7] => 3
[1] => 2
[3] => 2
[9] => 1
[12] => 1
[2] => 1
[13] => 1
)
)
)
Array
(
[0] => Array
(
[0] => Array
(
[0] => 4
[1] => 4
[2] => 7
[3] => 1
[4] => 7
[5] => 7
[6] => 3
[7] => 3
[8] => 4
[9] => 9
[10] => 12
[11] => 2
[12] => 13
[13] => 1
)
[1] => Array
(
[0] => 2014-06-18
[1] => 2014-06-10
[2] => 2014-06-05
[3] => 2014-06-05
[4] => 2014-06-12
[5] => 2014-06-11
[6] => 2013-12-12
[7] => 2014-07-23
[8] => 2014-05-13
[9] => 2014-06-01
[10] => 2014-06-12
[11] => 2014-06-04
[12] => 2014-06-04
[13] => 2014-06-11
)
)
)
I hope that what I understood is what you're really asking for. let's say your array definition is :
$arr = Array
(
0 => Array
(
0 => Array
(
0 => 4,
1 => 4,
2 => 7,
3 => 1,
4 => 7,
5 => 7,
6 => 3,
7 => 3,
8 => 4,
9 => 9,
10 => 12,
11 => 2,
12 => 13,
13 => 1
),
1 => Array
(
0 => "2014-06-18",
1 => "2014-06-10",
2 => "2014-06-05",
3 => "2014-06-05",
4 => "2014-06-12",
5 => "2014-06-11",
6 => "2013-12-12",
7 => "2014-07-23",
8 => "2014-05-13",
9 => "2014-06-01",
10 => "2014-06-12",
11 => "2014-06-04",
12 => "2014-06-04",
13 => "2014-06-11"
)
)
);
If you need to test if the date is lower than 6 month and then put their id, sales and date you need to use this code
$result = [];
$index=0;
foreach ($arr[0][0] as $key => $value)
{
$date1 = new DateTime($arr[0][1][$key]);
$date2 = new DateTime();
$diff = $date1->diff($date2);
$diff = ($diff->format('%y') * 12) + $diff->format('%m');
if($diff<=6)
{
$result[$index]['id'] = $key;
$result[$index]['sales'] = $value;
$result[$index]['date'] = $arr[0][1][$key];
$index++;
}
}
var_dump($result);
array_count_values() will give you the number of times each value appears in array 1.
$count = array_count_values($array[0][0]);
Result:
Array
(
[4] => 3
[7] => 3
[1] => 2
[3] => 2
[9] => 1
[12] => 1
[2] => 1
[13] => 1
)
Then you can use a loop to combine with array 2:
$result = array();
foreach($count as $key=>$val) {
$result[$array[0][1][$key]] = $val;
}
Result:
Array
(
[2014-06-12] => 3
[2014-07-23] => 3
[2014-06-10] => 2
[2014-06-05] => 1
[2014-06-01] => 1
[2014-06-04] => 1
[2014-06-11] => 1
)
See demo

Categories