reading large csv file contain comma with php - php

i have csv file that i need to read with php.I used 2 method but there is problem in theme.
methode i used are:
1- file_get_contents
2-fgetcsv
let explaine about csv file. the problem about the file is the fields contain comma that is used for delimiter and its bothering.
the first methode is fast but commas in the fiels make it work incorrectly like number seperator 14,200 . i fixed it withe a function named fixed number. but there is still random text that contain comma and doesnt follow any rule that i can fix them
the second method for large csv is very slow and i cant get out put to see that its working
the code for first methode is like:
$myFile = file_get_contents($file);
$lines = explode("\r\n",$myFile);//file to an array
while($counter <= count($lines)){
$data=$lines[$counter];
$tmp=fixnumbers($data);
$tmp=eregi_replace('"', '',$tmp);
$tmp=explode(',',$tmp);
if(count($tmp)> 0 ){
$newdata[$datacounter]=$tmp;//explode('*0*',$data);
$datacounter++;
}
$counter++;
}
the second methode is here :
$handle= fopen($file,"r");
$row=1;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
for ($c=0; $c < $num; $c++) {
$mydata[$row][$c]=$data[$c] . "<br />\n";
}$row++;
}
print "<div class=\"longList\"><pre>";
print_r($mydata);
print "</pre></div>";
fclose($file);
}

So I waited the minute to download the file, grabbed the first 5 records, and used a copy/paste of the fgetcsv example in the PHP manual.
First 5 records - https://termbin.com/23ti - saved as "sm_file.csv"
<?php
if (($handle = fopen("sm_file.csv", "r")) !== FALSE) {
$data=array();
$num=0;
while (($data[] = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num++;
}
fclose($handle);
print_r($data);
}
?>
[0] => Array
(
[0] => از تاريخ وصل 01/07/1397 - با برنامه
[1] => تاريخ گزارش: 29/09/1397
[2] => شماره گزارش: (3-5)
[3] => صفحه 1
[4] => گزارش قطع و وصل فيدرهاي فشار متوسط (نمونه 3)
[5] => ملاحظات
[6] => شرايط جوي
[7] => عملكرد ريكلوزر
[8] => رله عامل
[9] => خاموشي (MWh)
[10] => بار فيدر (A)
[11] => مدت قطع
[12] => زمان وصل
[13] => تاريخ وصل
[14] => زمان قطع
[15] => تاريخ قطع
[16] => نوع اشكال بوجود آمده
[17] => فيدر فشار متوسط
[18] => پست فوق توزيع
[19] => شماره پرونده
[20] => رديف
[21] => ناحيه اسالم
[22] =>
[23] => آفتابي
[24] => ندارد
[25] => ندارد
[26] => 0.21
[27] => 3
[28] => 132
[29] => 11:30
[30] => 1397/07/04
[31] => 09:18
[32] => 1397/07/04
[33] => جهت كار در حريم شبكه
[34] => گيسوم
[35] => اسا لم
[36] => 96,042,429,972
[37] => 1
[38] => 61292.56
[39] => جمع کل بار فيدر:
[40] => 393.85
[41] => جمع کل خاموشي:
[42] => 92,725
[43] => جمع مدت قطع:
)
Looks like data element 36 is the one you are having issues with, as you can see fgetcsv handles it fine, you just need to convert from a string to a number as you process the data. Just strip the commas.
<?php
if (($handle = fopen("sm_file.csv", "r")) !== FALSE) {
$data=array();
$num=0;
while (($data[] = fgetcsv($handle, 1000, ",")) !== FALSE) {
$data[(count($data)-1)][36]=str_replace(",","",$data[(count($data)-1)][36]);
}
fclose($handle);
print_r($data);
}
?>
Which gives
[36] => 96042429972
As for how long it takes, your full file of 2k records
User time (seconds): 0.12
System time (seconds): 0.09
Percent of CPU this job got: 43%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.52
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 41820
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 2448
Voluntary context switches: 18
Involuntary context switches: 55
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
on a modest i5 w/ 8gb ram. Not seeing any issues.

Related

Exporting a large CSV via PHP results in timeout/memory allocate error

I have a tool that allows data to be exported based on different time ranges. The problem I run into is that the longer the time range, the more data, and eventually the data set is too large -- resulting in either a timeout error or a memory allocation error.
Short of changing php.ini to have a larger max_execution_time, etc, is there a better way of doing this?
Here's my script to build the CSV (the user selects export, then this page is loaded):
$fileName = "export-".date("YmdHis");
$exportSignature = array(" ","Export","Generated by: ".$_SESSION['name'],date("Y-m-d H:i:s"));
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename='.$fileName.'.csv');
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
// run all the queries for the data
if($exportType == "list") {
include('include/query-compare.php');
} elseif($exportType == "analyze") {
include('include/query-analyze.php');
} elseif($exportType == "funnel") {
include('include/query-funnel.php');
} elseif($exportType == "funnelTrend") {
include('include/query-funnel-trends.php');
}
// add column headers
fputcsv($output,$columnHeaders);
// add row data
if($exportType == "list") {
foreach($comparison as $account) {
fputcsv($output,$account);
}
} elseif($exportType == "analyze") {
foreach($analyze as $account) {
fputcsv($output,$account);
}
} elseif($exportType == "funnel" || $exportType == "funnelTrend") {
foreach($funnel as $line) {
fputcsv($output,$line);
}
}
// add export signature
foreach($exportSignature as $line) {
fputcsv($output,array($line));
}
Here's a sample of the array that's used to create the rows. This is the variable -- if the time range is small there might be a few hundred entries in the array, if it's large, there's tens of thousands.
Array
(
[0] => Array
(
[0] => 1
[firstName] => Marco
[lastName] => R.
[title] => D
[email] => test#test.com
[company] => xx
[lSource] => xx
[lDetail] => xx
[lExact] => xx
[createdAt] => 2017-06-26 00:00:00
[nDate] => 2017-08-15
[cDate] => 2017-08-15
[cMoment] => xx
[mDate] => 2017-08-15
[mMoment] => xx
[Id] => 003Axx
[Type] => Contact
[accountId] => 001A0xx
[parentAccountId] =>
[accountOwner] => Kevin S.
[xx] => Nicholas W.
[accountType] => Prospect
[totalARR] => 0.00
[accountTier] =>
[ty] => XX
[industry] => Corporate Services
[secondaryIndustry] => IT Services and Consulting
[billingCountry] => Germany
[1] => 006Axx
[2] => PS (New Business)
[3] => Kevin S.
[4] => Nicholas W.
[5] => cc
[6] => New Business
[7] => Identify
[8] => 40000.00
[9] => 2017-08-16
[10] => 2018-07-27
[11] => 2017-08-16
[12] => 2017-08-21
)
)
I'd be fine with scheduling the export and emailing it to the user as well, I'm just not familiar with how I can have this large CSV constructed in the background without timing out.
EDIT: would it be a better option to queue the export in a database and have a cron job that looks for the exports, then runs the export in the background until complete? Since it's running via the cron it shouldn't have a timeout, right?
Use set_time_limit ( 0 ); at the beginning of your file. For example:
set_time_limit ( 0 );
$fileName = "export-".date("YmdHis");
Using set_time_limit ( 0 ); didn't help since I'm running on nginx and would run into gateway errors. Instead, I wound up queuing the downloads into a database table and executing the actual queries via a cron job, as those aren't subject to the same timeout limitations.

Converting Base64 encoded tab delimited file in PHP

I am writing a reporting app that needs to consume logs which have been stored in the DB as base 64 encoded strings. I am able to decode them no problem, however, I am having some trouble getting them to be fed into str_getcsv() properly.
Below is the data I am working with, the code and the outputs. It seems to me that once decoded the files are not recognizable as tab-delimited. However, if I decode it with this URL and and save as a text file, I can open it properly in excel.
https://www.base64decode.org/
In PHP however, it seems to be an issue with recognizing some of the tabs and the line breaks seem to completely go away. I think it has to do with the encoding, the DB table and column are both UTF-8. They are being recognized as ASCII - which is a subset of UTF-8, but I am not sure if they need to be explicitly UTF-8 for it to work (the site that works uses UTF-8).
The code: very simple (though at this point I may be going overboard with the encoding)
// get the stored result (laravel eloquent)
$media_result = MediaResult::where("video_id", "=", $media_benchmark->id)->firstOrFail();
# decode the access_log stored as b64 string
$tab_file = base64_decode(mb_convert_encoding($media_result->access_log, "UTF-8"));
$encoding = mb_detect_encoding($tab_file); // I was using iconv() so I grabbed this - it is always ASCII
$new_file = mb_convert_encoding($tab_file,'UTF-8');
$encoding_new = mb_detect_encoding($new_file);
#if I were to echo both encoding variables, it would be ASCII - no matter what I do.
# convert the supposed tab-delimited file into an array
$full_stats = str_getcsv($new_file, 0, "\t");
Here is a sample base64 encoded log:
VVJJCXNlcnZlckFkZHJlc3MJbnVtYmVyT2ZTZXJ2ZXJBZGRyZXNzQ2hhbmdlcwltZWRpYVJlcXVlc3RzV1dBTgl0cmFuc2ZlckR1cmF0aW9uCW51bWJlck9mQnl0ZXNUcmFuc2ZlcnJlZAludW1iZXJPZk1lZGlhUmVxdWVzdHMJcGxheWJhY2tTdGFydERhdGUJcGxheWJhY2tTZXNzaW9uSUQJcGxheWJhY2tTdGFydE9mZnNldAlwbGF5YmFja1R5cGUJc3RhcnR1cFRpbWUJZHVyYXRpb25XYXRjaGVkCW51bWJlck9mRHJvcHBlZFZpZGVvRnJhbWVzCW51bWJlck9mU3RhbGxzCW51bWJlck9mU2VnbWVudHNEb3dubG9hZGVkCXNlZ21lbnRzRG93bmxvYWRlZER1cmF0aW9uCWRvd25sb2FkT3ZlcmR1ZQlvYnNlcnZlZEJpdHJhdGVTdGFuZGFyZERldmlhdGlvbglvYnNlcnZlZE1heEJpdHJhdGUJb2JzZXJ2ZWRNaW5CaXRyYXRlCXN3aXRjaEJpdHJhdGUJaW5kaWNhdGVkQml0cmF0ZQlvYnNlcnZlZEJpdHJhdGUKaHR0cDovL3Zldm9wbGF5bGlzdC1saXZlLmhscy5hZGFwdGl2ZS5sZXZlbDMubmV0L3Zldm8vY2gxLzAxL3Byb2dfaW5kZXgubTN1OAk4LjI1NC4yMy4yNTQJMAkwCTAuNjc4MjgwNzA5CTEwOTk2MTIJMwkyMDE2LTA1LTEwIDE5OjIxOjE4ICswMDAwCTdBMTI5MERDLTE2MzAtNDlGQy1BQTY0LUNDNzZDMTgxQzcyQQk0MglMSVZFCTAuMjUzMjk3OTg0NjAwMDY3MQkxNi4wODMyNjU5NjAyMTY1MgkwCTAJMwkxOAkwCS0xCTI1NTcyOTAxLjM4MzMwNzg3CTE4MjA3OTg3LjMyODUyNTkJMTAxMTU1NDguNzgzODE4MjUJNDkyMDAwCTIxMDI1OTU1LjA1Mzg4OTI0Cmh0dHA6Ly92ZXZvcGxheWxpc3QtbGl2ZS5obHMuYWRhcHRpdmUubGV2ZWwzLm5ldC92ZXZvL2NoMS8wNi9wcm9nX2luZGV4Lm0zdTgJOC4yNTMuMzIuMTI2CTgJMAkzNS43NDAxNjM2MjIJMTIzNDgxOTcyCTQzCTIwMTYtMDUtMTAgMTk6MjE6MzQgKzAwMDAJN0ExMjkwREMtMTYzMC00OUZDLUFBNjQtQ0M3NkMxODFDNzJBCTU4LjAyODk5NDM1OAlMSVZFCTAJMjQxLjkyNjk3NTk2NTQ5OTkJMAkwCTQzCTI1OAkwCS0xCTQ2ODg1OTAzLjAzNTk4OTkzCTEwODA3NDU3LjM4MjQwNjY3CS0xCTQwMDAwMDAJMzE3ODIzNjAuNjE0NTI4NjM=
Here is the same string decoded:
URI serverAddress numberOfServerAddressChanges mediaRequestsWWAN transferDuration numberOfBytesTransferred numberOfMediaRequests playbackStartDate playbackSessionID playbackStartOffset playbackType startupTime durationWatched numberOfDroppedVideoFrames numberOfStalls numberOfSegmentsDownloaded segmentsDownloadedDuration downloadOverdue observedBitrateStandardDeviation observedMaxBitrate observedMinBitrate switchBitrate indicatedBitrate observedBitrate http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/01/prog_index.m3u8 8.254.23.254 0 0 0.678280709 1099612 3 2016-05-10 19:21:18 +0000 7A1290DC-1630-49FC-AA64-CC76C181C72A 42 LIVE 0.2532979846000671 16.08326596021652 0 0 3 18 0 -1 25572901.38330787 18207987.3285259 10115548.78381825 492000 21025955.05388924 http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/06/prog_index.m3u8 8.253.32.126 8 0 35.740163622 123481972 43 2016-05-10 19:21:34 +0000 7A1290DC-1630-49FC-AA64-CC76C181C72A 58.028994358 LIVE 0 241.9269759654999 0 0 43 258 0 -1 46885903.03598993 10807457.38240667 -1 4000000 31782360.61452863
Finally, here is the resulting array:
Array ( [0] => URI serverAddress numberOfServerAddressChanges mediaRequestsWWAN transferDuration numberOfBytesTransferred numberOfMediaRequests playbackStartDate playbackSessionID playbackStartOffset playbackType startupTime durationWatched numberOfDroppedVideoFrames numberOfStalls numberOfSegmentsDownloaded segmentsDownloadedDuration downloadOverdue observedBitrateStandardDeviation observedMaxBitrate observedMinBitrate switchBitrate indicatedBitrate observedBitrate http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/ [1] => 1/prog_index.m3u8 8.254.23.254 [2] => 0 [3] => .67828 [4] => 7 [5] => 9 1 [6] => 99612 3 2 [7] => 16- [8] => 5-1 [9] => 19:21:18 + [10] => [11] => [12] => [13] => 7A1290DC-1630-49FC-AA64-CC76C181C72A42 LIVE [14] => .2532979846 [15] => [16] => [17] => 671 16. [18] => 8326596 [19] => 21652 [20] => 03 18 [21] => -1255729 [22] => 1.3833 [23] => 787 182 [24] => 7987.3285259 1 [25] => 115548.78381825 492 [26] => [27] => [28] => 21025955.05388924 http://vevoplaylist-live.hls.adaptive.level3.net/vevo/ch1/06/prog_index.m3u88.253.32.126 8 [29] => 35.740163622123481972 43 2 [30] => 16- [31] => 5-1 [32] => 19:21:34 + [33] => [34] => [35] => [36] => 7A1290DC-1630-49FC-AA64-CC76C181C72A58. [37] => 28994358 LIVE [38] => 241.9269759654999 [39] => 043 258 [40] => -1468859 [41] => 3. [42] => 3598993 1 [43] => 8 [44] => 7457.3824 [45] => 667 -1 4 [46] => [47] => [48] => [49] => [50] => [51] => 31782360.61452863 )
Keep in mind that str_getcsv()
parses only one line of a csv file
expects the delimiter "\t" to be the second parameter, not the third
You probably want something like:
$full_stats = [];
foreach(explode("\n", $decoded) as $line) {
$full_stats[] = str_getcsv($line, "\t");
}
var_dump($full_stats);
This will output an array containing 3 arrays (aka rows) containing 24 items (aka columns) each.
See http://sandbox.onlinephpfunctions.com/code/1ccf5115df6f8c342ff7c7e451f3ea26e081197e for working example and generated output.
Regarding the import of data that contains line breaks you should switch to fget_csv() which handles line breaks correctly:
$csv = <<< eot
"first","my data
with line breaks"
"second", "simple data"
eot;
// We need to "convert" the string to a file handle
$fp = fopen('data://text/plain,' . $csv,'r');
while ($data = fgetcsv($fp)) {
var_dump($data);
}

preg match all in array searching for [ ]

i have found the solution mysqlf using:
foreach ($output as $value) {
if (strpos($value, "]:") > -1) {
$tal = substr($value, strpos($value, "]:") +3) . "<br>";
echo $tal;
}
}
this returns:
-210
-212
Thanks in advance.
I want to preg so i only get the line: [10] => [147]: -210
or both [10] => [147]: -210 and [21] => [148]: -212
how can i preg [147]: or is there a better way to get the specific information?
my array $output contains:
Array
(
[0] => modpoll 3.4 - FieldTalk(tm) Modbus(R) Master Simulator
[1] => Copyright (c) 2002-2013 proconX Pty Ltd
[2] => Visit http://www.modbusdriver.com for Modbus libraries and tools.
[3] =>
[4] => Protocol configuration: MODBUS/TCP
[5] => Slave configuration...: address = 1, start reference = 147, count = 1
[6] => Communication.........: 10.234.6.11, port 502, t/o 1.00 s, poll rate 1000 ms
[7] => Data type.............: 16-bit register, output (holding) register table
[8] =>
[9] => -- Polling slave...
[10] => [147]: -210
[11] => modpoll 3.4 - FieldTalk(tm) Modbus(R) Master Simulator
[12] => Copyright (c) 2002-2013 proconX Pty Ltd
[13] => Visit http://www.modbusdriver.com for Modbus libraries and tools.
[14] =>
[15] => Protocol configuration: MODBUS/TCP
[16] => Slave configuration...: address = 1, start reference = 148, count = 1
[17] => Communication.........: 10.234.6.11, port 502, t/o 1.00 s, poll rate 1000 ms
[18] => Data type.............: 16-bit register, output (holding) register table
[19] =>
[20] => -- Polling slave...
[21] => [148]: -212
)
$matches = preg_grep ('/^[147] (\w+)/i', $output);
print_r ($matches);
//only returns Array()
You need to escape the opening square bracket because [147] is seen as a character class that contains 1, 4 and 7
You can do this with:
$result=preg_grep('~^\[14(?:7|8)]:~',$rgData);
print_r($result);
You can find all that you want to know about escaping (or not) square brackets here

Can't read csv(Tab delimited) properly

I have simple csv file which is tab delimited which i have to use as it is because it is coming from somewhere and i hvae to read it and insert it into my db i have used a simple php code to read it
if(($handle = fopen("var/import/MMT29DEC.csv","r"))!==FALSE){
/*Skip the first row*/
fgetcsv($handle, 1000,chr(9));
while(($data = fgetcsv($handle,1000,chr(9)))!==FALSE){
print_r($data[0]);
}
}
When print_r the data it shows like
Array ( [0] => 01SATAPC [1] => 40ATAPC [2] => [3] => 21P [4] => SERIAL ATA POWER CABLE [5] => 0.00 [6] => 2.00 [7] => 0 [8] => Power Supplies [9] => SERIAL ATA POWER CABLE [10] =>
4 TO 15 PIN 160MM
[11] => [12] => [13] => [14] => MELBHO [15] => 0.000 [16] => [17] => Order to Order [18] => 4 [19] => 2013-01-18 )
Which is the desired result but when i go to access the particular column value using the $data['index'] e.g. $data[8] or $data[1] it weirdly giving me garbage values says for some iterations it give me right values but after 10-15 rows its starting giving me the some numbers and other column values..... i don't know whats is going on with this as far as i know it should be formatting issue i have tried open the file in excel and its coming fine....
#ravisoni are you sure that the second parameter to fgetcsv of 1000 is longer than the longest line in your file? Try setting it to 0 as the docs say [php.net/fgetcsv] and see if that makes a difference.
if(($handle = fopen("var/import/MMT29DEC.csv","r"))!==FALSE){
/*Skip the first row*/
fgetcsv($handle, 0,chr(9));
while(($data = fgetcsv($handle,0,chr(9)))!==FALSE){
print_r($data[0]);
}
}

Find missing numbers in array

I'm trying to find each missing number in an array like the following.
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 [20] => 21 [21] => 22
[22] => 23 [23] => 24 [24] => 25 [25] => 26 [26] => 27 [27] => 28 [28] => 29
[29] => 30 [30] => 31 [31] => 32 [32] => 33 [33] => 34 [34] => 35 [35] => 36
[36] => 37 [37] => 38 [38] => 39 [39] => 40 [40] => 41 [41] => 42 [42] => 43
[43] => 44 [44] => 45 [45] => 46 [46] => 47 [47] => 48 [48] => 49 [49] => 50
[50] => 51 [51] => 52 [52] => 53 [53] => 54 [54] => 55 [55] => 56 [56] => 57
[57] => 58 [58] => 59 [59] => 60 [60] => 61 [61] => 62 [62] => 63 [63] => 64
[64] => 67 [65] => 68 [66] => 69
)
The numbers 65,66 are missing in this particular array.
My question how do I figure out which numbers are missing with the help of PHP. Specifically what I need to find out is the lowest missing number.
Why: Because then I can assign that number to a member as an id.
You can make use of array_diff and range functions as:
// given array. 3 and 6 are missing.
$arr1 = array(1,2,4,5,7);
// construct a new array:1,2....max(given array).
$arr2 = range(1,max($arr1));
// use array_diff to get the missing elements
$missing = array_diff($arr2,$arr1); // (3,6)
I'm assuming the number is the element, not the key, of the array. I'm also assuming that the numbers start from 1, not 0.
$Expected = 1;
foreach ($InputArray as $Key => $Number)
{
if ($Expected != $Number)
{
break;
}
$Expected++;
}
echo $Number;
For big sorted arrays of unique numbers, you can binary search the array for either the lowest or highest unused number. Cost=Log2N. Example: 65536 items can be searched in 16 loops since
if ( arr[hi] - arr[lo] > hi - lo )
... there are unused numbers in that range ...
So (I don't know PHP, but it can be translated...):
lo = first entry index
hi = last entry index
if ( arr[hi] - arr[lo] == hi - lo )
return arr[hi]+1; // no gaps so return highest + 1
do
{
mid = (lo + hi) / 2;
if ( arr[mid] - arr[lo] > mid - lo ) // there is a gap in the bottom half somewhere
hi = mid; // search the bottom half
else
lo = mid; // search the top half
} while ( hi > lo + 1 ); // search until 2 left
return arr[lo]+1;
If given input is not in sorted order and size of input is very large then we can use following logic in any programming language:
Algorithm
bring smaller chunk into memory from large input
initialize three variables say min = 0, max = 0 and missingIds = []
scan smaller chunked input from left to right
if scannedValue found in missingIds
then,
pop scannedValue from missingIds
go to next value;
If scanned value is near to min
then,
find all the missing numbers between scannedValue and min, push into missingIds
min = scannedValue;
Else if scanned value is near to max
then,
find all the missing numbers between scannedValue and max, push into missingIds
max = scannedValue;
repeat above steps until large input scanned from left to right
Example in PHP
<?php
$largeInput = [40,41,42,43,44,45,1,2,3,4,5,6,7,8,9,10,11,12,13,14,35,36,37,38,39,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,67,68,69,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34];
$missingIds = [];
$min = 0;
$max = 0;
$chunkSize = 10;
$chunkNo = 0;
$currentInput = array_slice($largeInput, $chunkNo, $chunkSize);
while(count($currentInput) > 0) {
foreach($currentInput as $id) {
if(in_array($id,$missingIds)) {
$missingIds = array_diff($missingIds,[$id]);
continue;
}
if($id <= $min) {
$distMin = $min - $id;
if($distMin > 2) {
$tempArr = range($id+1,$min-1);
$missingIds = array_merge($missingIds, $tempArr);
$tempArr = [];
} else if ($distMin > 1) {
$tempArr = [$id+1];
$missingIds = array_merge($missingIds, $tempArr);
$tempArr = [];
}
$min = $id;
} else if ($id >= $max){
$distMax = $id - $max;
if($distMax > 2) {
$tempArr = range($max+1,$id-1);
$missingIds = array_merge($missingIds, $tempArr);
$tempArr = [];
} else if ($distMax > 1) {
$tempArr = [$max+1];
$missingIds = array_merge($missingIds, $tempArr);
$tempArr = [];
}
$max = $id;
}
}
$chunkNo++;
$currentInput = array_slice($largeInput, $chunkNo, $chunkSize);
}
print_r($missingIds);
//$idArrayMissing = array([0] => 1, [1] => 2, [2] => 4, [3] => 5, [4] => 6, [5] => 7);
$idArrayMissing = array(1, 2, 4, 5, 6, 7);
//$idArrayFull = array([0] => 1, [1] => 2, [2] => 3, [3] => 4, [4] => 5, [5] => 6);
$idArrayFull = array(1, 2, 3, 4, 5, 6);
function gap($arr)
{
while (list($k, $v) = each($arr))
if ($k != ($v-1))
return $k;
return -1;
}
print "ok:" . gap($idArrayMissing) . "<br/>\n";
print "full:" . gap($idArrayFull) . "<br/>\n";
The return of the gap function can be 2 values:
-1 could indicate that the array has been traversed and there are no free slots or
$k+1 which could indicate that the first free slot is on the end of the array.
It can also be done easily by using in_array() function like this:
// lets say $InputArray has all the data
// lets declare a variable which we will search inside the $InputArray array and lets initialize it with either 0 or 1 or with the minimum value found inside $InputArray
$start_counting = 1;
$max_value = count($InputArray);
if (!(in_array($start_counting, $InputArray)))
{
echo "Value: ".$start_counting." is missing!"."<br>" ;
}
else{
if($start_counting <= $max_value -1)
{$start_counting++;}
}
else if($start_counting > $max_value -1)
{
echo "All missing numbers printed!"
}
}

Categories