How to print an array of characters in swift without a line terminator - swift

This should be simple to solve. When I try printing an array of characters in a Swift playground, I see each character printed with a end of line terminator...
For Example when I type this in a Swift Playground.
var strTokenizeMe = "Go Pro"
for chrInStr in strTokenizeMe { print(chrInStr,"*")}
This prints
G
o
P
r
o
Now I do NOT want and end of line terminator, so I add terminator: " " at the end of the print statement, like this ...
for chrInStr in strTokenizeMe { print(chrInStr, terminator: " ")}
But when I do this NOTHING gets printed.

In a Playground you need to print one final newline, otherwise the output
is not flushed to the output window:
for chrInStr in strTokenizeMe { print(chrInStr, terminator: " ")}
print()
A (not necessarily better) alternative would be to concatenate
the characters before printing them:
print(strTokenizeMe.map(String.init).joined(separator: " "))
The problem does not occur when running a compiled program, because
the standard output is always flushed on program exit.

Related

How to get non-escaped apostrophe from .components(separatedBy: CharacterSet)

How I can get components(separatedBy: CharacterSet) to return the substrings so that they do not contain escaped apostrophes or single quotes?
When I print the resulting array, I want it to not include the backslash character.
I am using a playground to manipulate text and produce output in the terminal that I can copy and use outside of Xcode, so I want to strip the escape character from the string representation produced in the terminal output.
var str = "can't,,, won't, , good-bye, Santa Claus"
var delimiters = CharacterSet.letters.inverted.subtracting(.whitespaces)
delimiters = delimiters.subtracting(CharacterSet(charactersIn: "-"))
delimiters = delimiters.subtracting(CharacterSet(charactersIn: "'"))
var result = str.components(separatedBy: delimiters)
.map({ $0.trimmingCharacters(in: .whitespaces) })
.filter({ !$0.isEmpty })
print(result) // ["can\'t", "won\'t", "good-bye", "Santa Claus"]
What you are asking for is a metaphysical impossibility. You cannot want anything about how print prints. It's only a representation in the log.
Your strings do not actually contain any backslashes, so what's the problem? How the print command output notates them is irrelevant. You might as well "want" the print command to translate your strings into French. No, that's not what it does. It just prints, and the way it prints is the way it prints.
Another way to look at it: An array doesn't contain square brackets at both ends. And a string doesn't contain double-quotes at both ends. Those are things you might write in order express those things as literals, but they are not real as part of the actual object. Well, I don't see you objecting to those!
Basically, if you want to control the output of something, you write an output routine. If you're doing to rely on print, just accept the funny old way it writes stuff and move on.

How to replace double quotes with a newline character in spark scala

I am new to spark. I have a huge file which has data like-
18765967790#18765967790#T#20130629#00#31#2981546 " "18765967790#18765967790#T#20130629#19#18#3240165 " "18765967790#18765967790#T#20130629#18#18#1362836
13478756094#13478756094#T#20130629#31#26#2880701 " "13478756094#13478756094#T#20130629#19#18#1230206 " "13478756094#13478756094#T#20130629#00#00#1631440
40072066693#40072066693#T#20130629#79#18#1270246 " "40072066693#40072066693#T#20130629#79#18#3276502 " "40072066693#40072066693#T#20130629#19#07#3321860
I am trying to replace " " with new line character so that my output looks like this-
18765967790#18765967790#T#20130629#00#31#2981546
18765967790#18765967790#T#20130629#19#18#3240165
18765967790#18765967790#T#20130629#18#18#1362836
13478756094#13478756094#T#20130629#31#26#2880701
13478756094#13478756094#T#20130629#19#18#1230206
13478756094#13478756094#T#20130629#00#00#1631440
40072066693#40072066693#T#20130629#79#18#1270246
40072066693#40072066693#T#20130629#79#18#3276502
40072066693#40072066693#T#20130629#19#07#3321860
I have tried with-
val fact1 = sc.textFile("s3://abc.txt").map(x=>x.replaceAll("\"","\n"))
But this doesn't seem to be working. Can someone tell what I am missing?
Edit1- My final output will be a dataframe with schema imposed after splitting with delimeter "#".
I am getting below o/p-
scala> fact1.take(5).foreach(println)
18765967790#18765967790#T#20130629#00#31#2981546
18765967790#18765967790#T#20130629#19#18#3240165
18765967790#18765967790#T#20130629#18#18#1362836
13478756094#13478756094#T#20130629#31#26#2880701
13478756094#13478756094#T#20130629#19#18#1230206
13478756094#13478756094#T#20130629#00#00#1631440
40072066693#40072066693#T#20130629#79#18#1270246
40072066693#40072066693#T#20130629#79#18#3276502
40072066693#40072066693#T#20130629#19#07#3321860
I am getting extra blank lines which is further troubling me to create dataframe. This might seem simple here, but the file is huge, also the rows containing " " are long. In the question I have put only 2 double quotes but they can be more than 40-50 in numbers.
There are more than one quote in between textes, which is creating multiple line breaks. You either need to remove additional quotes before replace or empty lines after replace:
.map(x=>x.replaceAll("\"","\n").replaceAll("(?m)^[ \t]*\r?\n", ""))
Reference: Remove all empty lines
You might be missing implicit Encoders and you try the code as below
spark.read.text("src/main/resources/doubleQuoteFile.txt").map(row => {
row.getString(0).replace("\"","\n") // looking to replace " " with next line
row.getString(0).replace("\" \"","\n") // looking to replace " " with next line
})(org.apache.spark.sql.Encoders.STRING)

Try/catch item with strange syntax

Strange syntax in this code fragment:
var result =
try {
Process(bl).!!
} catch {
case e: Exception =>
log.error(s"Error on query: ${hql}\n")
"Etc etc" + "Query: " + hql
}
Why not using separator like , or ; after log.error(s"...")?
The catch statement is returning one or two values?
PS: there are a better Guide tham this one, with all Scala syntax alternatives?
Newline characters can terminate statements
semi ::= ‘;’ | nl {nl}
Scala is a line-oriented language where statements may be terminated
by semi-colons or newlines. A newline in a Scala source text is
treated as the special token “nl” ...
IMHO, newline character \n is just as good of a statement terminator as semicolon character ;. However, it may have an advantage over ; in that it is invisible to humans which perhaps has the benefit of less code clutter. It might seem strange because it is invisible, but rest assured it is there silently doing its job delimiting statements. Perhaps it might become less strange if we try to imagine it like so
1 + 42'\n' // separating with invisible character \n
1 + 42; // separating with visible character ;
Note that we must use semicolons when writing multiple statements on the same line
log.error(s"Error on query: ${hql}\n"); "Etc etc" + "Query: " + hql
Addressing the comment, AFAIU, your confusion stems from misunderstanding how pattern matching anonymous functions and block expressions work. Desugared handler function
case e: Exception =>
log.error(s"Error on query: ${hql}\n")
"Etc etc" + "Query: " + hql
is equivalent to something like
case e: Exception => {
log.error(s"Error on query: ${hql}\n"); // side-effect statement that just logs an error
return "Etc etc" + "Query: " + hql; // final expression becomes the return value of the block
}
Hence, "one block with two branches into it" is not the correct understanding, instead there is only a single code path through your particular function.

Carriage return character not being matched in Swift

I'm trying to parse a file that (apparently) ends its lines with carriage returns, but they aren't being matched as such in Swift, despite having the same UTF8 value. I can see possible fixes for the problem, but I'm curious as to what these characters actually are.
Here's some sample code, with the output below. (CR is set using Character("\r"), although I've tried it using "\r" as well.
try f.forEach() { c in
print(c, terminator:" ") // DBG
if (c == "\r") {
print("Carriage return found!")
}
print(String(c).utf8.first!, terminator:" ")//DBG
print(String(describing:pstate)) // DBG
...
case .field:
switch c {
case CR,LF :
self.endline()
pstate = .eol
When it reaches the end of line (which shows up as such in my text editors), I get this:
. 46 field
0 48 field
13 field
I 73 field
It doesn't seem to be matching using == or in the switch statement. Is there another approach I should be using for this character?
(I'll note that the parsing works fine with files that terminate in newlines.)
I determined what the problem was. By looking at c.unicodeScalars I discovered that the end of line character was in fact "\r\n", not just "\r". As seen in my code I was only taking the first when printing it out as UTF-8. I don't know if that's something from String.forEach or in the file itself.
I know that there are tests to determine if something is a newline. Swift 5 has them directly (c.isNewline), and there is also the CharacterSet approach as noted by Bill Nattaner.
I'm happier with something that will work in my switch statement (and thus I'll define each one explicitly), but that might change if I expect to deal with a wider variety of files.
I'm a little hazy as to what the f.forEach represents, but if your variable c is of type Character then you could replace your if statement with:
if "\(c)".rangeOfCharacter( from: CharacterSet.newlines ) != nil
{
print("Carriage return found!")
}
That way you won't have to invent a list of all-possible new line characters.

Passing delimiter as command line argument in scala and use it to split a string

I have a scala program where I take "\t" as a command line input.
Inside the program I want to split a string on the basis of the delimiter passed from command line.
val splitter = args(0).charAt(0)
if(splitter == '\t')
println("true")
else
println("false")
This prints "false" and splitter "\".
The above method works for "," comma delimiter.
Please suggest how can I pass a tab or any other delimiter as command line parameter and use it for the splitting purpose.
It's because if you're passing "\t" in on the command line, then it's coming in as a two-character string \t, not a single-character tab. To do what you want, you can't just take the first character (charAt(0)) since you'll miss the t. Instead you'll have to unescape it by converting from the string \t to the tab character.
An easy way:
val splitter = args(0) match {
case "\\t" => '\t'
case x => x.head // same as x.charAt(0)
}