I have a function with two parameters which accepts string and a list. I now need to pass a third String parameter into this function which defaults to an empty string. Heres my function :
Here is how I call the function:
rows("{CALL " + storedProc + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}",param1,param2,param3)
Here is the function
List<GroovyRowResult> rows(String query,java.lang.Object[] parameterMap){
......
}
Now, in the above function, the input parameters is as follows:
query = {CALL reportStoredProc(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}
parameterMap = [param1,param2,param3]
When I put a thrid default paramter in the function like:
List<GroovyRowResult> rows(String query,java.lang.Object[] parameterMap, String test=''){
......
}
if i pass "Hello" as test the string in test is taken as an elemtn in the list. So, now the parmeters will be:
query = {CALL reportStoredProc(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}
parameterMap = [param1,param2,param3,Hello]
test = ''
Is, there a workaround here to pass the third parameter without add it into the list? It might be a silly question but Im stuck with this for some time now.
Note: to call stored procedure I am compelled to use rows instead of call or execute. Also, I cant use [] to pass parameterMap while calling the function.
Also, the test must be the third parameter
Thanks,
Related
I have a function that returns a string of a method I want to call.
For example:
I call the function and it returns the string "price". I then want to use the word price to call another method ( contractObject.price() )
Is there any way to accomplish this in Node JS?
Yes, you can use square brackets:
let methodName = "price";
contractObject[methodName]();
contractObject["price"] is equivalent to contractObject.price.
This will work.
const functionToCall = yourFunction(); // this returns "price"
// call the price function like this
contractObject[functionToCall]();
Ended up figuring out the answer. If I make the whole function a string and then use eval( ) it calls the method I wanted
I need to insert a parameter into this:
row: workbook.getWorksheet("VittorioZigiotto").getRange("VittorioZigiotto[237]:Vittorioigiotto[241]")
The parameter need to be where now there is "237" and neet to depend on a cell in the workbook. For example, MONEYPAGE1!A1+5. Any ideas?
You can get the value you'd like instead of 237 from MONEYPAGE!A1 by doing something like:
const valueFromMPA1 = workbook.getWorksheet("MONEYPAGE").getRange("A1").getValue(); // use getValue for convenience since it's a single cell
const rowString = `VittorioZigiotto[${valueFromMPA1}]:VittorioZigiotto[${valueFromMPA1 + 5}]`; // this is a js/ts way to construct strings with params
// and then pass that in as the argument ...
const row = workbook.getWorksheet("VittorioZigiotto").getRange(rowString);
I'm not sure of your exact scenario, but also take a look at .getRangeByIndexes (instead of getRange), which lets you pass numeric row/column values instead of having to construct a string argument.
I'm not sure how to explain this, but when I run
console.log`1`
In google chrome, I get output like
console.log`1`
VM12380:2 ["1", raw: Array[1]]
Why is the backtick calling the log function, and why is it making a index of raw: Array[1]?
Question brought up in the JS room by Catgocat, but no answers made sense besides something about templating strings that didn't really fit why this is happening.
It is called Tagged Template in ES-6 more could be read about them Here, funny I found the link in the starred section of the very chat.
But the relevant part of the code is below (you can basically create a filtered sort).
function tag(strings, ...values) {
assert(strings[0] === 'a');
assert(strings[1] === 'b');
assert(values[0] === 42);
return 'whatever';
}
tag `a${ 42 }b` // "whatever"
Basically, its merely tagging the "1" with console.log function, as it would do with any other function. The tagging functions accept parsed values of template strings and the values separately upon which further tasks can be performed.
Babel transpiles the above code to
var _taggedTemplateLiteralLoose = function (strings, raw) { strings.raw = raw; return strings; };
console.log(_taggedTemplateLiteralLoose(["1"], ["1"]));
As you can see it in the example above, after being transpiled by babel, the tagging function (console.log) is being passed the return value of the following es6->5 transpiled code.
_taggedTemplateLiteralLoose( ["1"], ["1"] );
The return value of this function is passed to console.log which will then print the array.
Tagged template literal:
The following syntax:
function`your template ${foo}`;
Is called the tagged template literal.
The function which is called as a tagged template literal receives the its arguments in the following manner:
function taggedTemplate(strings, arg1, arg2, arg3, arg4) {
console.log(strings);
console.log(arg1, arg2, arg3, arg4);
}
taggedTemplate`a${1}b${2}c${3}`;
The first argument is an array of all the individual string characters
The remaining argument correspond with the values of the variables which we receive via string interpolation. Notice in the example that there is no value for arg4 (because there are only 3 times string interpolation) and thus undefined is logged when we try to log arg4
Using the rest parameter syntax:
If we don't know beforehand how many times string interpolation will take place in the template string it is often useful to use the rest parameter syntax. This syntax stores the remaining arguments which the function receives into an array. For example:
function taggedTemplate(strings, ...rest) {
console.log(rest);
}
taggedTemplate `a${1}b${2}c${3}`;
taggedTemplate `a${1}b${2}c${3}d${4}`;
Late to the party but, TBH, none of the answers give an explanation to 50% of the original question ("why the raw: Array[1]")
1. Why is it possible to call the function without parenthesis, using backticks?
console.log`1`
As others have pointed out, this is called Tagged Template (more details also here).
Using this syntax, the function will receive the following arguments:
First argument: an array containing the different parts of the string that are not expressions.
Rest of arguments: each of the values that are being interpolated (ie. those which are expressions).
Basically, the following are 'almost' equivalent:
// Tagged Template
fn`My uncle ${uncleName} is ${uncleAge} years old!`
// function call
fn(["My uncle ", " is ", " years old!"], uncleName, uncleAge);
(see point 2. to understand why they're not exactly the same)
2. Why the ["1", raw: Array[1]] ???
The array being passed as the first argument contains a property raw, wich allows accessing the raw strings as they were entered (without processing escape sequences).
Example use case:
let fileName = "asdf";
fn`In the folder C:\Documents\Foo, create a new file ${fileName}`
function fn(a, ...rest) {
console.log(a); //In the folder C:DocumentsFoo, create a new file
console.log(a.raw); //In the folder C:\Documents\Foo, create a new file
}
What, an array with a property ??? ???
Yes, since JavaScript arrays are actually objects, they can store properties.
Example:
const arr = [1, 2, 3];
arr.property = "value";
console.log(arr); //[1, 2, 3, property: "value"]
I have this list:
service_name_status=[a-service=INSTALL, b-service=UPGRADE, C-service=UPGRADE, D-service=INSTALL]
And I need to iterate through this list so the first element will be the value of a parameter called "SERVICE_NAME" and the second element will be the value of a parameter called "HELM_COMMAND",
after asserting those values to the parameters I will run my command that uses those parameters and then continue the next items on the list which should replace the values of the parameters with items 3 and 4 and so on.
So what I am looking for is something like that:
def service_name_status=[a-service=INSTALL, b-service=UPGRADE, C-service=UPGRADE, D-service=INSTALL]
def SERVICE_NAME
def HELM_COMMAND
for(x in service_name_status){
SERVICE_NAME=x(0,2,4,6,8...)
HELM_COMMAND=x(1,3,5,7,9...)
println SERVICE_NAME=$SERVICE_NAME
println HELM_COMMAND=$HELM_COMMAND
}
the output should be:
SERVICE_NAME=a-service
HELM_COMMAND=INSTALL
SERVICE_NAME=b-service
HELM_COMMAND=UPGRADE
SERVICE_NAME=c-service
HELM_COMMAND=UPGRADE
SERVICE_NAME=d-service
HELM_COMMAND=INSTALL
and so on...
I couldn't find anything that takes any other element in groovy, any help will be appreciated.
The collection you want is a Map, not a List.
Take note of the quotes in the map, the values are strings so you need the quotes or it won't work. You may have to change that at the source where your data comes from.
I kept your all caps variable names so you will feel at home, but they are not the convention.
Note the list iteration with .each(key, value)
This will work:
Map service_name_status = ['a-service':'INSTALL', 'b-service':'UPGRADE', 'C-service':'UPGRADE', 'D-service':'INSTALL']
service_name_status.each {SERVICE_NAME, HELM_COMMAND ->
println "SERVICE_NAME=${SERVICE_NAME}"
println "HELM_COMMAND=${HELM_COMMAND}"
}
EDIT:
The following can be used to convert that to a map. Be careful, the replaceAll part is fragile and depends on the data to always look the same.
//assuming you can have it in a string like this
String st = "[a-service=INSTALL, b-service=UPGRADE, C-service=UPGRADE, D-service=INSTALL]"
//this part is dependent on format
String mpStr = st.replaceAll(/\[/, "['")
.replaceAll(/=/, "':'")
.replaceAll(/]/, "']")
.replaceAll(/, /, "', '")
println mpStr
//convert the properly formatted string to a map
Map mp = evaluate(mpStr)
assert mp instanceof java.util.LinkedHashMap
I have a list of strings I get as a result of splitting a string. I need to remove the surrounding quotes from the strings in the list. Using method chaining how can I achieve this? I tried the below, but doesn't work.Says type interference failed.
val splitCountries: List<String> = countries.split(",").forEach{it -> it.removeSurrounding("\"")}
forEach doesn't return the value you generate in it, it's really just a replacement for a for loop that performs the given action. What you need here is map:
val splitCountries: List<String> = countries.split(",").map { it.removeSurrounding("\"") }
Also, a single parameter in a lambda is implicitly named it, you only have to name it explicitly if you wish to change that.