Given any character from a to z, what is the most efficient way to get the next letter in the alphabet using PHP?
Answers
$chars = range('a', 'z');
$shift = 5;
$shifted = array_merge(array_slice($chars, $shift), array_slice($chars, 0, $shift));
$alphabet = array_combine($chars, $shifted);
Since there are 26 characters in your alphabet you can only shift them by 26 characters, meaning there are 26 possible combinations.
See the manual for the increment operator:
PHP follows Perl's convention when dealing with arithmetic operations on character variables and not C's. For example, in PHP and Perl $a = 'Z'; $a++; turns $a into 'AA', while in C a = 'Z'; a++; turns a into '[' (ASCII value of 'Z' is 90, ASCII value of '[' is 91). Note that character variables can be incremented but not decremented and even so only plain ASCII characters (a-z and A-Z) are supported. Incrementing/decrementing other character variables has no effect, the original string is unchanged.
I wouldn't normally answer my own question but given that Google are closing off the v3 Sheets API in March 2020 I suspect others may come across this problem.
As I have mentioned in comments against the original question there is no existing means in the v4 API of accessing Cell Formats. Therefore there is no option to loop through one range and apply formats to another.
My workaround solution is to copy / paste the preceding row (the default PASTE_NORMAL will copy all values, formulas, formats, and merges https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#pastetype) and then overwrite the newly pasted row with the required values. This gives me the required values with the existing formatting in the new row:-
$sheetId = null;
$worksheetSheets = $this->spreadsheetService->spreadsheets->get($this->spreadsheetId)->sheets;
foreach($worksheetSheets as $sheet){
$sheetTitle = $sheet->properties['title'];
if ($sheetTitle === $this->worksheetTitle){
$sheetId = $sheet->properties['sheetId'];
break;
}
}
$copyRange = new Google_Service_Sheets_GridRange();
$copyRange->setSheetId($sheetId);
$copyRange->setStartRowIndex($nextRow - 2);
$copyRange->setEndRowIndex($nextRow - 1);
$copyRange->setStartColumnIndex(0);
$copyRange->setEndColumnIndex(400);
$pasteRange = new Google_Service_Sheets_GridRange();
$pasteRange->setSheetId($sheetId);
$pasteRange->setStartRowIndex($nextRow - 1);
$pasteRange->setEndRowIndex($nextRow);
$pasteRange->setStartColumnIndex(0);
$pasteRange->setEndColumnIndex(400);
$copypasteRequest = new Google_Service_Sheets_CopyPasteRequest();
$copypasteRequest->setSource($copyRange);
$copypasteRequest->setDestination($pasteRange);
//$copypasteRequest->pasteType(CopyPasteType.PASTE_NORMAL);
$request = new Google_Service_Sheets_Request();
$request-> setCopyPaste($copypasteRequest);
$batchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
$batchUpdateRequest->setRequests($request);
// Need to check if sheet has an existing empty row to paste into
$finalRowRange = $this->worksheet['range'];
$finalRowStartPosition = strpos($this->worksheet['range'],':') + 2;
$finalRow = intval(substr($finalRowRange,$finalRowStartPosition));
if($finalRow <= $pasteRange['startRowIndex']){ // startRowIndex is a zero based array range, i.e. 348 actually corresponds to row 349 on sheet.
$appendDimensionRequest = new Google_Service_Sheets_AppendDimensionRequest();
$appendDimensionRequest->setSheetId($sheetId);
$appendDimensionRequest->setDimension("ROWS");
$appendDimensionRequest->setLength(1);
$appendRequest = new Google_Service_Sheets_Request();
$appendRequest->setAppendDimension($appendDimensionRequest);
$appendEmptyRowBatchUpdateRequest = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
$appendEmptyRowBatchUpdateRequest->setRequests($appendRequest);
$this->spreadsheetService->spreadsheets->batchUpdate($this->spreadsheetId, $appendEmptyRowBatchUpdateRequest);
}
$this->spreadsheetService->spreadsheets->batchUpdate($this->spreadsheetId, $batchUpdateRequest);
// The actual data values insert
$this->spreadsheetService->spreadsheets_values->update(
$this->spreadsheetId,
$updateRange,
$valueRange,
$conf
);
I hope this may be of some use to someone in future.
function Last7Days () {
var result = [];
for (var i=0; i<7; i++) {
var d = new Date();
d.setDate(d.getDate() - i);
result.push( formatDate(d) )
}
return(result.join(','));
}
FIDDLE
Or another solution for the whole thing
function Last7Days () {
return '0123456'.split('').map(function(n) {
var d = new Date();
d.setDate(d.getDate() - n);
return (function(day, month, year) {
return [day<10 ? '0'+day : day, month<10 ? '0'+month : month, year].join('/');
})(d.getDate(), d.getMonth(), d.getFullYear());
}).join(',');
}
FIDDLE
The most efficient way of doing this in my opinion is to just increment the string variable.
As seen incrementing
'z'
give'aa'
if you don't want this but instead want to reset to get an'a'
you can simply check the length of the resulting string and if its>1
reset it.