I have this function and running flawless on coldfusion 2016 and lucee but wen i run in cf11, it fails.
i am trying to understand how can i make it work with cf11
private any function isListInList(list1, list2, returnBoolean = true){
var rv = false;
var matches = [];
listToArray(list1).each(
function(element) {
if(listToArray(list2).containsNoCase(element)){
rv = true;
arrayAppend(matches, element);
}
}
);
return arguments.returnBoolean ? rv : matches;
}
This version of your function will compile and run on CF11
private any function isListInList(list1, list2, returnBoolean = true){
var rv = false;
var matches = [];
var arr1 = listToArray(list1);
var arr2 = listToArray(list2);
arr1.each(
function(element) {
if(arr2.findNoCase(element)){
rv = true;
arrayAppend(matches, element);
}
}
);
return arguments.returnBoolean ? rv : matches;
}
This version that uses a for() loop will be optimized for large arrays since it will short circuit the loop when it finds a match and you just want the boolean back.
private any function isListInList(list1, list2, returnBoolean = true){
var arr1 = listToArray(list1);
var arr2 = listToArray(list2);
var rv = false;
var matches = [];
for( var element in arr1 ) {
if(arr2.findNoCase(element)){
if( returnBoolean ) {
return true;
} else {
arrayAppend(matches, element);
}
}
}
return arguments.returnBoolean ? false : matches;
}
Related
So here is my Data Class
data class Bestellung (var id:Int = 0, var anzahl:Int = 1, var speise:String? = null)
my List
private var bestellungList = ArrayList<Bestellung>()
Trying to update the list if "speise" equals "s" but its not working without any error..
if (bestellungList.contains(Bestellung(speise = s))) {
var i = bestellungList.indexOf(Bestellung(speise = s))
bestellungList.set(i, Bestellung(anzahl = +1))
problem is contains
pls try this if you want to check first:
if(bestellungList.any{ it.speise == "s" }) {
// do add logic
} else {
// do something else
}
The problem is your contains part. Replace it like this
val index = bestellungList.indexOfFirst {
it.speise == s
}
if (index >= 0) {
bestellungList[index] = Bestellung(anzahl = +1)
}
if (bestellungList.any{ it.speise == "s" }) {
bestellungList.addAll(Bestellung(anzahl = +1))
} else {
// handle else statement also
}
I always have reduce issue on practicing, like following map and reduce, if I add more document or add more field to emit in the map and reduce like following. it will return values as [], not sure what occur this?
problemNumber : doc.problemNumber,
UserId: idv,
event : doc.event
......
Map
function(doc) {
if(doc.event){
var idv = null;
for (var idu in doc.Data.users){
if (doc.eventData.users[idu].userTypeCode == "M"){
idv = doc.Data.users[idu].UserId;
}
}
var newDoc = {
problemNumber : doc.problemNumber,
UserId: idv,
event : doc.event
};
emit(null, newDoc);
}
}
Reduce
function(keys, values, rereduce) {
var result = [];
var closeMap = {};
for (var i=0; i<values.length; i++){
var doc = values[i];
if (doc.event=='CLOSE'){
closeMap[doc.problemNumber] = 1;
}
}
for (var i=0; i<values.length; i++){
var doc = values[i];
if (doc.event=='OPEN'){
if (closeMap[doc.problemNumber]){
doc.event = 'CLOSE';
}
result.push(doc);
}
}
return result;
}
I am making a merge code to take data from my spreadsheet and populate merge tags in a Google Doc. The part of the code I am unable to write correctly is the part that writes the tags back to the Google Doc. I have been able to locate the tags but the code doesn't replace them.
Here is what I've written so far.
function mergeApplication() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Merge Data");
var range = sheet.getActiveRange();
var formSheet = ss.getSheetByName("Form Responses");
var lastRow = formSheet.getLastRow();
var lastColumn = sheet.getMaxColumns();
function checkAndComplete() {
var urlColumn = lastColumn;
var checkColumn = (urlColumn - 1);
var checkRange = sheet.getRange(2, checkColumn, (lastRow - 1), 1);
var check = checkRange.getBackgrounds();
var red = "#ff0404";
var yellow = "#ffec0a";
var green = "#3bec3b";
for (var i = 0; i < check.length; i++) {
if (check[i] == green) {
continue;
} else {
var statusCell = sheet.getRange((i+2), checkColumn, 1, 1);
var urlCell = sheet.getRange((i+2), urlColumn, 1, 1);
var dataRow = sheet.getRange((i+2), 1, 1, (lastColumn - 2));
function mergeTasks() {
function docCreator() {
// var templateConditionRange = sheet.getRange((i+2), column);
// var templateConditionCheck = templateConditionRange.getValues();
var docTemplate1 = DriveApp.getFileById(id);
// var docTemplate2 = DriveApp.getFileById(id);
// var docTemplate3 = DriveApp.getFileById(id);
var folderDestination = DriveApp.getFolderById(id);
var clientName = sheet.getRange((i+2), 3).getValue();
var date = sheet.getRange((i+2), 1).getValue();
// if (templateConditionCheck[i] == "") {
var docToUse = docTemplate1;
// }
// if (templateConditionCheck[i] == "") {
// var docToUse = docTemplate2;
// }
// if (templateConditionCheck[i] == "") {
// var docToUse = docTemplate3;
// }
var docName = "Merge Tester Doc for " + clientName + " [" + date + "]";
var docCopy = docToUse.makeCopy(docName, folderDestination);
var docId = docCopy.getId();
var docURL = DriveApp.getFileById(docId).getUrl();
var docToSend = DriveApp.getFileById(docId);
var docBody = DocumentApp.openById(docId).getBody().getText();
function tagReplace() {
var taggedArray = [docBody.match(/\<{2}[\w\d\S]+\>{2}/g)];
var headerArray = [sheet.getRange(1, 1, 1, (lastColumn - 2)).getValues()];
var dataArray = [dataRow.getValues()];
var strippedArray = [];
Logger.log("The preliminary length of taggedArray is " + taggedArray.length);
Logger.log(taggedArray);
function tagStrip() {
for (var t = 0; t < taggedArray.length; t++) {
var strippedString = taggedArray[t].slice(2, -3).toString();
strippedArray.push(strippedString);
Logger.log("The current strippedArray length is " + strippedArray.length);
}
Logger.log("The final strippedArray length is " + strippedArray.length);
Logger.log("The final taggedArray length is " + taggedArray.length);
Logger.log("The final, completed strippedArray is " + strippedArray);
}
function dataMatch() {
for (var s = 0; s < strippedArray.length;) {
for (var h = 0; h < headerArray.length;) {
if (strippedArray[s] == headerArray[h]) {
docBody.replaceText(taggedArray[s].String(), dataArray[h].String());
h=0;
s++;
} else {
h++;
}
}
}
}
tagStrip;
dataMatch;
}
function emailCreator() {
var emailTag = sheet.getRange((i+2), (urlColumn - 2)).getValue();
var emailBody = HtmlService.createHtmlOutputFromFile("Email Template").getContent();
var personalizers = clientName + " [" + date + "]";
var subject = "Merge Tester Email for " + personalizers;
MailApp.sendEmail(emailTag, subject, emailBody, {
name: "Christopher Anderson",
attachments: [docToSend],
html: emailBody,
});
}
tagReplace();
statusCell.setBackground(yellow);
emailCreator();
urlCell.setValue(docURL)
}
statusCell.setBackground(red);
docCreator();
statusCell.setBackground(green);
}
mergeTasks();
}
}
}
checkAndComplete();
}
The problem section is here:
function tagReplace() {
var taggedArray = [docBody.match(/\<{2}[\w\d\S]+\>{2}/g)];
var headerArray = [sheet.getRange(1, 1, 1, (lastColumn - 2)).getValues()];
var dataArray = [dataRow.getValues()];
var strippedArray = new Array();
Logger.log("The preliminary length of taggedArray is " + taggedArray.length);
Logger.log(taggedArray);
function tagStrip() {
for (var t = 0; t < taggedArray.length; t++) {
var strippedString = taggedArray[t].slice(2, -3).toString();
strippedArray.push(strippedString);
Logger.log("The current strippedArray length is " + strippedArray.length);
}
Logger.log("The final strippedArray length is " + strippedArray.length);
Logger.log("The final taggedArray length is " + taggedArray.length);
Logger.log("The final, completed strippedArray is " + strippedArray);
}
function dataMatch() {
for (var s = 0; s < strippedArray.length;) {
for (var h = 0; h < headerArray.length;) {
if (strippedArray[s] == headerArray[h]) {
docBody.replaceText(taggedArray[s].String(), dataArray[h].String());
h=0;
s++;
} else {
h++;
}
}
}
}
tagStrip;
dataMatch;
}
It doesn't even log anything having to do with strippedArray.
It seems to be skipping over that section entirely.
Am I using the correct method of completing this task and/or is there a simpler way of doing it?
It's worth mentioning that my tags in the doc have 2 "<>" around them. That's the reason for my RegEx looking how it does.
Also, when logging the .length of taggedArray, it returns a value of 1.
You never actually call tagStrip which is supposed to work on strippedArray.
You declare it with function tagStrip(){} and later you reference the function with tagStrip; but you never actually call it. The same is happening with dataMatch.
Try calling the two functions by writing
tagStrip();
dataMatch();
If you don't include the parentheses you don't call it you just run the function Objects as statements.
Here is a portion of code I use in my add-on Simply Send, I use the same <<>> merge tags.
//copy template
var mDocDrive = doc.makeCopy(title, folder);
var mDoc = DocumentApp.openById(mDocDrive.getId());
var mDocDriveApp = DriveApp.getFileById(mDoc.getId());
var docToAttach = mDoc.getUrl();
var driveToShare = mDocDriveApp;
// replace text inside template
var body = mDoc.getBody();
body.replaceText("<<SS Title>>", title);
body.replaceText("<<timestamp>>", lastR.timestamp);
body.replaceText("<<username>>", lastR.email);
for (i in lastR.theResponses){
var cur = lastR.theResponses[i];
var name = cur.title;
name = name.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); // this will allow fields that include special characters.
var response = cur.response;
var searchPattern = "<<"+name+">>";
body.replaceText(searchPattern, response);
}
// this will replace any unused tags with nothing.
var ques = getQuestionList();
for (j in ques){
var curq = ques[j].name;
curq = curq.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
var searchPattern2 = "<<"+curq+">>";
body.replaceText(searchPattern2, "");
}
mDoc.saveAndClose();
//create pdf
if (mmDefaults.shareAs == "pdf"){
// uncomment if you want to make the pdf in the merge folder
var asPdf = mDoc.getAs('application/pdf');
asPdf.setName(mDoc.getName()+ ".pdf");
var pdf = DriveApp.createFile(asPdf);
folder.addFile(pdf);
DriveApp.removeFile(pdf);
mDocDriveApp.setTrashed(true);
var docToAttach = pdf;
driveToShare = pdf;
}
I've been receiving an error from Amazon web service - InvalidParameterValue
Either Action or Operation query parameter must be present.
I believe it is most likely due to the signature being incorrect as the XML document and Header matches that of a test I did in their scratchpad.
Does anything stand out as being incorrect?
Thanks,
Clare
private static string ConstructCanonicalQueryString(SortedDictionary<string, string> sortedParameters)
{
var builder = new StringBuilder();
if (sortedParameters.Count == 0)
{
builder.Append(string.Empty);
return builder.ToString();
}
foreach (var kvp in sortedParameters)
{
builder.Append(PercentEncodeRfc3986(kvp.Key));
builder.Append("=");
builder.Append(PercentEncodeRfc3986(kvp.Value));
builder.Append("&");
}
var canonicalString = builder.ToString();
return canonicalString.Substring(0, canonicalString.Length - 1);
}
private static string PercentEncodeRfc3986(string value)
{
value = HttpUtility.UrlEncode(string.IsNullOrEmpty(value) ? string.Empty : value, Encoding.UTF8);
if (string.IsNullOrEmpty(value))
{
return string.Empty;
}
value = value.Replace("'", "%27")
.Replace("(", "%28")
.Replace(")", "%29")
.Replace("*", "%2A")
.Replace("!", "%21")
.Replace("%7e", "~")
.Replace("+", "%20")
.Replace(":", "%3A");
var sbuilder = new StringBuilder(value);
for (var i = 0; i < sbuilder.Length; i++)
{
if (sbuilder[i] != '%')
{
continue;
}
if (!char.IsLetter(sbuilder[i + 1]) && !char.IsLetter(sbuilder[i + 2]))
{
continue;
}
sbuilder[i + 1] = char.ToUpper(sbuilder[i + 1]);
sbuilder[i + 2] = char.ToUpper(sbuilder[i + 2]);
}
return sbuilder.ToString();
}
public string SignRequest(Dictionary<string, string> parametersUrl, Dictionary<string, string>
parametersSignture)
{
var secret = Encoding.UTF8.GetBytes(parametersSignture["Secret"]);
var signer = new HMACSHA256(secret);
var pc = new ParamComparer();
var sortedParameters = new SortedDictionary<string, string>(parametersUrl, pc);
var orderedParameters = ConstructCanonicalQueryString(sortedParameters);
var builder = new StringBuilder();
builder.Append(parametersSignture["RequestMethod"])
.Append(" \n")
.Append(parametersSignture["EndPoint"])
.Append("\n")
.Append("/\n")
.Append(orderedParameters);
var stringToSign = builder.ToString();
var toSign = Encoding.UTF8.GetBytes(stringToSign);
var sigBytes = signer.ComputeHash(toSign);
var signature = Convert.ToBase64String(sigBytes);
return signature.Replace("=", "%3D").Replace("/", "%2F").Replace("+", "%2B");
}
public class ParamComparer : IComparer<string>
{
public int Compare(string p1, string p2)
{
return string.CompareOrdinal(p1, p2);
}
}
The issue was that the Action wasn't included correctly into the Request
Lets say P is a regex pattern defined as "AB" where A,B are subpatterns. There is a string T which is tested against pattern P. I want to find out if T is a partial match of P, this means T machtes against A but not B since it is not long enough to match B. T could be a match if it was combined with a string U which is matched by B.
var A = "[a-z]{3}";
var B = "[0-9]{2}"
var P = A + B;
var T = "abc";
var U = "20";
var macthes_T = regex(P, T); // false
var matches_U = regex(P, U); // false
var matches_TU = regex(P, T + U); // true
var couldMatch_T = magic(P, T); // true
var couldMatch_U = magic(P, U); // false
var couldMatch_TU = magic(P, T + U); // true
Now I want to doe this recursive on A since its the "start" of P and "implement" the magic function for input T, which would look like this:
var A_1 = "[a-z]";
var A_2 = "[a-z]";
var A_3 = "[a-z]";
var A = A_1 + A_2 + A_3;
// T="" would return false
// T="a" would return true
var hasChar(T) {
return length(T) > 0;
}
// T="ab" would return a and T is "b"
var getChar(T) {
var c = T[0];
T = substring(T, 1);
return c;
}
// Let x element of [a-z]
// would return true for "", "x", "xx", "xxx"
// would return false for any other input T
var magic_A(T) {
if(!hasChar(T)) {
return true;
}
if(!regex(A_1, getChar(T))) {
return false;
}
if(!hasChar(T)) {
return true;
}
if(!regex(A_2, getChar(T))) {
return false;
}
if(!hasChar(T)) {
return true;
}
if(!regex(A_3, getChar(T))) {
return false;
}
return true;
}
umm something like this?
\b(a|ab)[a-z]*
this one check if there's a or ab, then any char between a-z following behind and wrap the whole word as matching
http://regexr.com/3aa5n
just noticed that your code won't work with regex
here's some reference http://www.dotnetperls.com/regex-match