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
)
)
Related
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.
There is probably a really simple way to do this but i can't work it out.
Array ( [0] => Array ( [] => US [1] => U.S. [2] => 21 [3] => 34 [4] => 33 [5] => 35 [6] => 39 [7] => 50 [8] => 61 ) [1] => Array ( [] => 79 [1] => 45 [2] => 84 [3] => 89 [4] => 59 [5] => 64 [6] => 34 [7] => 58 [8] => 55 ) [2] => Array ( [] => 63 [1] => 105 [2] => 68 [3] => 62 [4] => 64 [5] => 67 [6] => CL [7] => Chile [8] => 56 ) [3] => Array ( [] => 40 [1] => 40 [2] => 63 [3] => 37 [4] => 57 [5] => 64 [6] => 59 [7] => 53 [8] => 68 ) [4] => Array ( [] => 70 [1] => 66 [2] => 88 [3] => 48 [4] => 76 [5] => 83 [6] => 80 [7] => 53 [8] => 45 ) [5] => Array ( [] => 44 [1] => 51 [2] => 52 [3] => [4] => [5] => [6] => [7] => [8] => ) )
This is my array. There will all ways be the same number of object (9) in each however the number currently at 6 may increase.
I need to get the 1st item in each so for the 1st one i need (US) I'm stuck as if i put
echo $array[0][1];
Then I get U.S. however i need the first item (US) so i tried both
echo $array[0][0];
echo $array[0][];
Neither return a value. What am i doing wrong?
Using an “empty” string as key in an associative array is possible in PHP.
It is distinctively different from any other, non-empty string key values - so it fulfills the most basic requirement you have for such a key (and the PHP guys didn’t seem to see any need to explicitly prevent this.)
$arr = [
'foo' => 'bar',
'' => 'baz',
];
print_r would show this as
Array
(
[foo] => bar
[] => baz
)
and var_dump’ed it would look like this,
array(2) {
["foo"]=>
string(3) "bar"
[""]=>
string(3) "baz"
}
The latter makes it more obvious that the key is in fact an empty string, and therefor $arr[""] resp. $arr[''] can be used to access this element.
One might consider this one of PHP’s peculiarities - it does work, but it is hardly ever used in practice, because it just does not make the most sense for most use cases.
The other answers offer good explanation about the empty key that I won't reiterate, but a simple way to get the first item in each of the sub-arrays is to map the reset function which we mentioned in the comments over your main array.
$firsts = array_map('reset', $your_array);
This should work regardless of what the key is.
If I were you, I would begin by asking myself why my array has an empty key, my best guess is that you set your subarrays with keys instead of letting it being indexed incrementally by writing something like this :
array(
'' => 'US', // Maybe a '0' was intended to be there, and it's a type.
'1' => 'U.S.',
'2' => '21',
'3' => '34',
'4' => '33',
// etc...
);
In that case, you may benefit from fixing your code, or at least updating it so that your array is confortable to use, for example by removing the keys so that they are replaced with successive indexes.
Anyway, if you want to use that current array, do this :
echo $array[0][''];
Or iterate through it :
foreach ($array as $sub) {
echo $sub[''],'<br>';
}
If you don't have control over how the array is set, you can also reindex it using array_values(). That function takes an array as an argument and returns its values with successive indexes instead of its original keys :
foreach ($array as $key => $sub) {
$array[$key] = array_values($sub);
}
That code should give you the same array than before with the exception that the empty keys are replaced with 0.
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>
I am using before code to get every first id and remove that id but it show error undefine offset.
I don't understand What i missed in the below code ?
$products = Array
(
[32] => Array
(
[0] => 44
[1] => 45
[2] => 926
[3] => 927
[4] => 930
[5] => 931
)
[41] => Array
(
[0] => 928
[1] => 933
[2] => 969
[3] => 970
[4] => 971
[5] => 972
[6] => 973
[7] => 974
[8] => 975
[9] => 976
[10] => 977
[11] => 978
[12] => 979
[13] => 980
[14] => 981));
$in_array = array();
for($i=0;$i<12;)
{
foreach($products as &$brands):
if(isset($brands[0]))
{
$id = $brands[0];// get the first element
unset( $brands[0]); // have remove that element form products
// But here it show error undefine offset 0
array_push($in_array,$id);
/*if(($key1 = array_search($id, $brands)) !== false) {
unset($brands[$key1]);
}*/
//I tried this too same error
$i++;
}
endforeach;
}
$brands[0] doesn't seem to exist(I only see 32 and 41 in your code).
If you'd like to remove the first element in $products[32] than you need another foreach in your foreach:
foreach($products as $brands) {
foreach($brands as $brand) {
//Here is where you can reach $brand[0](Which is 44 in $products[32])
}
}
If you'd like to remove the first element of the array, you can use array_shift
By the help of mr #CaptainCarl i change my loop it working fine
for($i=0;$i<12;)
{
foreach($products_ids as $key=>$brands):
if(isset($brands[0]))
{
$id = $brands[0];
array_push($in_array,$id);
array_shift($brands);
$i++;
}
$products_ids[$key] = $brands;
endforeach;
}
I have a set of nested arrays.
[data] is the top level array.
The lower level arrays are all identified by incremental numbers, dynamically assigned...essentially each sub-array identifies a row/record of information.
How would I extract the count of the sub-arrays? I need to be able to do this to post this data into a DB.
The number of sub-arrays is dynamic, and can change depending on what data I am parsing through.
[data] => Array
(
[0] => Array
(
[id] => 3475
[name] => Player1
[score] => 11870
[rank] => 213
[total_cities] => 2
[crown] => None
[alliance_id] => 134
[title] => Earl
[fame_total] => 509875
[fame_rank] => 381
[defeated_total] => 3436
[defeated_rank] => 376
[plunder_total] => 1388754
[plunder_rank] => 245
)
[1] => Array
(
[id] => 3523
[name] => Player2
[score] => 1978
[rank] => 281
[total_cities] => 1
[crown] => None
[alliance_id] => 134
[title] => Baron
[fame_total] => 0
[fame_rank] => 448
[defeated_total] => 0
[defeated_rank] => 448
[plunder_total] => 0
[plunder_rank] => 436
)
[2] => Array
(
[id] => 73
[name] => Player3
[score] => 1308
[rank] => 304
[total_cities] => 1
[crown] => None
[alliance_id] => 134
[title] => Marquess
[fame_total] => 5604153
[fame_rank] => 237
[defeated_total] => 37270
[defeated_rank] => 229
[plunder_total] => 68130
[plunder_rank] => 335
)
I used a combination of the methods highlighted by Marc B and Thanos to get my desired result
This is the code I used:
$count = 0;
foreach($data as $data=>$inner_array){
$count = $count+1;
}
echo $count;
I ran it with a test data set with 143 unique rows, and I got that echo back, so life is good.
Thanks guys.
Simplest method:
$count = 0;
foreach($mainarray as $subarray)
$count += count($subarray);
}
Let's assume $data is your main array:
This one prints the name of each inner array (0, 1, 2... for your example) and then counts each sub-array items:
echo "Number of sub-arrays: ".count($online_time); //optional
foreach($data as $inner_array=>$data_of_inner_array) {
echo $inner_array;
echo " --- ".count($data_of_inner_array);
echo "<br/>";
}
i assume output will be
Number of sub-arrays: 3
0 --- 14
1 --- 14
2 --- 14