xquery substring and then concat - substring

I am trying to use substring and concat functions in an XQuery statement together.
Here is what I have:
fn:concat(fn:substring({data($x/DueDate)},1,4),fn:substring({data($x/DueDate)},6,2),fn:substring({data($x/(DueDate))},9,2))
The value for DueDate in my xml is: 2013-06-27.
I expected the above function to return: 20130704.
Instead, this is what I get:
fn:concat(fn:substring(2013-06-27,1,4),fn:substring(2013-06-27,6,2),fn:substring(2013-06-27,9,2))
I am confused as to why!

If you use it within an element, you need to surround the expression with curly parentheses, like:
{
fn:concat(
fn:substring(data($x/DueDate), 1, 4),
fn:substring(data($x/DueDate), 6, 2),
fn:substring(data($x/DueDate), 9, 2)
)
}

Are you sure that your DueDate value is actually 2013-06-27? Here is what each individual call to substring equals:
substring('2013-06-27',1,4)
=> 2013
fn:substring('2013-06-27',6,2)
=> 06
fn:substring('2013-06-27',9,2)
=> 27
substring() starts at the 1-indexed character number passed in the second param and copies the number of characters passed in the third param.

Clean up you formatting and bracketing (remove unnecessary curly brackets, remove some parentheses) and you will get some valid code:
fn:concat(
fn:substring(data($x/DueDate), 1, 4),
fn:substring(data($x/DueDate), 6, 2),
fn:substring(data($x/DueDate), 9, 2)
)
There is a much shorter and more readable version, too:
fn:string-join(fn:tokenize($x/DueDate, '-'))
Or even replace using regular expressions:
fn:replace($x/DueDate, '-', '')

Related

Using M4, how to extract code from a string and increase indentation?

I need to write a M4 macro that extracts + transforms code between curly braces.
I want to transform
{
import math
a_list = [1, 4, 9, 16]
if val:
print([math.sqrt(i) for i in a_list])
else:
print("val is False")
print("bye bye")
}
to
import math
a_list = [1, 4, 9, 16]
if val:
print([math.sqrt(i) for i in a_list])
else:
print("val is False")
print("bye bye")
The macro has to trim the whitespace before the first { and after the last }.
Because this is python code, nside the curly braces, the relative indentation must be preserved.
Because the output of the macro will be outputted somewhere, needed a certain level of indentation.
The macro should also be able to add extra indentation (=some number of spaces), e.g. given as an argument.
The project is already using m4sugar, so the quotes are [ and ].
Thanks.

Swift: how to convert readLine() input " [-5,20,8...] " to an Int array

I already run the search today and found a similar issue here, but it not fully fix the issue. In my case, I want to convert readLine input string "[3,-1,6,20,-5,15]" to an Int array [3,-1,6,20,-5,15].
I'm doing an online coding quest from one website, which requires input the test case from readLine().
For example, if I input [1,3,-5,7,22,6,85,2] in the console then I need to convert it to Int array type. After that I could deal with the algorithm part to solve the quest. Well, I think it is not wise to limit the input as readLine(), but simply could do nothing about that:(
My code as below, it could deal with positive array with only numbers smaller than 10. But for this array, [1, -3, 22, -6, 5,6,7,8,9] it will give nums as [1, 3, 2, 2, 6, 5, 6, 7, 8, 9], so how could I correctly convert the readLine() input?
print("please give the test array with S length")
if let numsInput = readLine() {
let nums = numsInput.compactMap {Int(String($0))}
print("nums: \(nums)")
}
Here is a one liner to convert the input into an array of integers. Of course you might want to split this up in separate steps if some validation is needed
let numbers = input
.trimmingCharacters(in: .whitespacesAndNewlines)
.dropFirst()
.dropLast()
.split(separator: ",")
.compactMap {Int($0)}
dropFirst/dropLast can be replaced with a replace using a regular expression
.replacingOccurrences(of: "[\\[\\]]", with: "", options: .regularExpression)
Use split method to get a sequence of strings from an input string
let nums = numsInput.split(separator: ",").compactMap {Int($0)}

I wonder what is different between separator and terminator in printing?

I am wondering about this printing thing. You could notice this code concept different between this code concept.
print(1, 2, 3, 4, 5, separator: "...")
//1...2...3...4...5
and
for n in 1...5 {
print(n, separator: " ", terminator: "...")
}
// 1...2...3...4...5...
I thought separator supposed be space for add text each of the items but terminators for default the newlines as known \n which you could see newlines sign if you were using the swift playground as well. If you put that three periods on the separator could not display that '...' on loops but printing can. I get a bit confuse about this code. so Let me know about this code. Might I was wrong at those things. I was learning about Swift.
As documented for the print(_:separator:terminator:) method:
separator: A string to print between each item.
terminator: The string to print after all items have been printed.
This is per call to print. So the separator is only useful when you provide more than one value to print.
print(arg1, arg2, ..., argN, separator: someSeparator, terminator: someTerminator)
This results in:
arg1 someSeparator arg2 someSeparator ... someSeparator argN someTerminator
(but without the spaces which I added for clarity).
When you only print one value, such as in the code in your question, the separator isn't used at all so you are only seeing the terminator at the end of each value printed.
Code such as:
print(1, 2, 3, 4, 5, separator: " ", terminator: "...")
will give the results you seem to be looking for:
1 2 3 4 5...
separator is the text to print between the vales given to print.
terminator is the text to print after all values were printed. so:
print(val1, val2, val3, ..., separator: "<SEP>", terminator: "<TERM>")
will print
val1<SEP>val2<SEP>val3<SEP>...<TERM>
if only one value is given to print, then it will NOT print the separator, because it has nothing to separate! (you don't separate one value from itself). but it will print the terminator given (or the default terminator, if one is not supplied).
therefor,
print(1, 2, 3, 4, 5, separator: "...")
//1...2...3...4...5
will print the values 1, 2, 3, 4, 5 separated by "..." and terminated by the default terminator,
and
for n in 1...5 {
print(n, separator: " ", terminator: "...")
}
// 1...2...3...4...5...
will print every number from 1 to 5, with the text ... after every number, and
will not print the separator, because the print is given only one value to print.

Datastage, Remove only last two characters of string

This function: Trim(In.Col, Right(In.Col, 2), 'T') works unless the last >2 characters are the same.
What I want:
abczzzz -> abczz
What I get:
abczzzz -> abc
How do I solve this?
The "T" option removes all trailing occurrences. Since you are limiting your input to only two characters with the Right() function, the second occurence will never be a trailing char.
It sounds though like you are just doing a substring..? If so, then you might just want to do a substring [ ] instead.
expression [ [ start, ] length ]
In.Col[(string length) - 2]
I prefer the Left() function, although it's equivalent here, as it's self-documenting.
Left(InLink.MyString, Len(InLink.MyString) - 2)

Does CoffeeScript have something like wildcard binding in destructing assignment?

In Scala, I can do things like:
val List(first, _, third) = List(1, 2, 3)
// first = 1
// third = 3
I currently have some CoffeeScript code in which I'm also not interested some elements in the array. Ideally, I would like to use a wildcard, like I'm doing in Scala.
[first, _, third] = [1, 2, 3]
Now, this does work, but it also adds this assignment:
_ = 2
… which is clearly not what I want. (I'm using underscore.) What's the preferred way of ignoring values in the array?
By the way, I'm using this for regular expression matching; the regular expression I'm using has optional groups that are really there for matching only, not to get any real data out.
match = /^(([a-z]+)|([0-9]+)) (week|day|year)(s)? (before|after) (.*)$/.exec str
if match?
[__, __, text, number, period, __, relation, timestamp] = match
…
In your specific case you could bypass the whole problem by using non-capturing groups in your regex:
(?:x)
Matches x but does not remember the match. These are called non-capturing parentheses. The matched substring can not be recalled from the resulting array's elements [1], ..., [n] or from the predefined RegExp object's properties $1, ..., $9.
If I'm reading your code right, you'd want:
/^(?:([a-z]+)|([0-9]+)) (week|day|year)(?:s)? (before|after) (.*)$/
You could also replace (?:s)? with s? since there's no need to group a single literal like that:
/^(?:([a-z]+)|([0-9]+)) (week|day|year)s? (before|after) (.*)$/
In either case, that you leave you with:
[__, text, number, period, relation, timestamp] = match
You could use an array slice to get rid of the leading __:
[text, number, period, relation, timestamp] = match[1..]
The match[1..] is a hidden call to Array.slice since the destructuring isn't smart enough (yet) to just skip match[0] when breaking match up. That extra method call may or may not matter to you.
There is no way to have wildcard assignments like that. You could use a double underscore __, like this
[first, __, third] = [1, 2, 3]
Personally, I would name the second variable in a way that makes sense, even if it is not used afterwards.