I want to compare two characters. Something like this:
if ('a' > 'b')
However, the above code is comparing two strings.
How do I do this in Dart?
Dart doesn't have a 'char' or 'character' type. You can get the UTF-16 character code from any point in a string, and compare that.
Use codeUnitAt to get the actual character code from a string.
if ('a'.codeUnitAt(0) > 'b'.codeUnitAt(0))
See the codeUnitAt docs: https://api.dartlang.org/docs/channels/stable/latest/dart_core/String.html#codeUnitAt
String in Dart implements the Comparable interface. You can use compareTo to compare them.
String a = 'a';
String b = 'b';
String c = 'a';
print('value: ${a.compareTo(b)}'); // prints "value: -1"
print('value: ${a.compareTo(c)}'); // prints "value: 0"
print('value: ${b.compareTo(a)}'); // prints "value: 1"
Related
I am new to iOS development, while I was going through string interpolation. I want to know the clarification between these print statement's output:
var value = "5"
print("Values is: \(value)")
print("Values is:", value)
print("Values is: " + value)
Output is : Values is: 5
Values is: 5
Values is: 5
Practically all three forms do the same thing.
The differences are
String interpolation syntax. You can put everything within the inner parentheses which responds to the CustomStringConvertible protocol.
Variadic parameter syntax. print is declared func print(_ items: Any...,. Any... means you can pass multiple items comma separated which are treated as array.
String concatenation syntax : The strings are concatenated with the + operator
If 5 was Int rather than String forms 1 and 2 are valid but not form 3
For such a question, we should take a look at print(_:separator:terminator:) parameters:
1) items: is a variadic parameter of type Any, which means that you can pass zero or more items to it. Example:
print() // passing nothing
print("Hello") // passing single item (String)
print(101, 40.45, false, ["Hi", "Greetings"]) // passing multiple items
2) separator: the string to print between each item (as mentioned in its documentation). Example:
print(101, 40.45, false, ["Hi", "Greetings"], separator: " <=> ")
// 101<=>40.45<=>false<=>["Hi", "Greetings"]
3) terminator: the string to print after all items have been printed (as mentioned in its documentation). Example:
print(101, 40.45, false, ["Hi", "Greetings"], terminator: " ==>")
// 101 40.45 false ["Hi", "Greetings"] ==>
Back to your cases:
First, keep in mind that for all of your three cases you are passing only items parameter; It is valid -for sure- because separator and terminator have default values as " " and \n.
Now, for the first and third print statements
print("Values is: \(value)")
print("Values is: " + value)
what happens is: actually you are dealing with Strings, it is not about the print itself. You can do interpolation in strings as well as using the + for concatenating strings without the print:
// interpolation:
let name = "Jack"
let greetingMessage = "Greetings, \(name)"
print(greetingMessage) // => Greetings, Jack
// concatenating:
let concatenated = "Greetings" + ", " + "Sara"
print(concatenated) // => "Greetings" + ", " + "Sara"
Which means that you are passing a single String item, regardless of doing interpolation or concatenation for it.
You could also check The + function implementation in Swift. Basically, it is an append!
The second print statement:
print("Values is:", value)
What happens here is: you are passing two items; According to the default value for separator, the output is:
Values is: 5
As:
Values is: 5
^ ^^
| ||__ item #2
item #1 |
|
default separator (" ")
In this print statement output is the same but there is different like in first statement use \(value) variable within the string data.
The second statement append data in your string value with keep one space
The third statement just concat two value (it does not keep space between two value), In this statement "+" sign used as operator overloading to concat two value
let value = "5"
print("Values is: \(value)") //use variable value within string
print("Values is:", value) //append value, with keep one space
print("Values is: " + value) //just concat two value
var value = "5"
print("Values is: (value)")
// Print the value as a part of the the string. If you use print("Values is:(value)"), it will print the output without space.
print("Values is:", value)
// you do not need to add a separate space to add the value to sting. It will automatically add the value to the string with a space.
print("Values is: " + value)
// It will show error if you use integer value "Binary operator '+' cannot be applied to operands of type 'String' and 'Int'"
otherwise it will work. And if you want to concatenate int with sting you need to do something like below:-
print("Values is: " + String(value))
// it is normal concatenate number with string
All the above will print the exact
I want to parse a string like "ParseThis" or "parseThis" into a vector of strings like ["Parse", "This"] or ["parse", "this"] using the nom crate.
All attempts I've tried do not return the expected result. It's possible that I don't understand yet how to use all the functions in nom.
I tried:
named!(camel_case<(&str)>,
map_res!(
take_till!(is_not_uppercase),
std::str::from_utf8));
named!(p_camel_case<&[u8], Vec<&str>>,
many0!(camel_case));
But p_camel_case just returns a Error(Many0) for parsing a string that starts with an uppercase letter and for parsing a string that starts with a lowercase letter it returns Done but with an empty string as a result.
How can I tell nom that I want to parse the string, separated by uppercase letters (given there can be a first uppercase or lowercase letter)?
You are looking for things that start with any character, followed by a number of non-uppercase letters. As a regex, that would look akin to .[a-z]*. Translated directly to nom, that's something like:
#[macro_use]
extern crate nom;
use nom::anychar;
fn is_uppercase(a: u8) -> bool { (a as char).is_uppercase() }
named!(char_and_more_char<()>, do_parse!(
anychar >>
take_till!(is_uppercase) >>
()
));
named!(camel_case<(&str)>, map_res!(recognize!(char_and_more_char), std::str::from_utf8));
named!(p_camel_case<&[u8], Vec<&str>>, many0!(camel_case));
fn main() {
println!("{:?}", p_camel_case(b"helloWorld"));
// Done([], ["hello", "World"])
println!("{:?}", p_camel_case(b"HelloWorld"));
// Done([], ["Hello", "World"])
}
Of course, you probably need to be careful about actually matching proper non-ASCII bytes, but you should be able to extend this in a straight-forward manner.
I have an integer which I want to convert to a string with leading zeros.
So I have 1 and want to turn it into 01. 14 should turn into 14 not 014.
I tried:
let str = (string 1).PadLeft(2, '0') // visual studio suggested this one
let str = (string 1).PadLeft 2 '0'
let str = String.PadLeft 2 '0' (string 1)
But neither work :(
When I search for something like this with F# I get stuff with printfn but I don't want to print to stdout :/
Disclaimer: This is my first F#
You can use sprintf which returns a string rather than printing to stdout. Any of the print functions that start with an s return a string.
Use %0i to pad with zeroes. Add the length of the intended string between 0 and i. For example, to pad to four zeroes, you can use:
sprintf "%04i" 42
// returns "0042"
In some languages, like C# for example, you can create a string in the following way:
"String {0} formatted {1} "
And then format it with String.format by passing in the values to format.
The above declaration is good, because you don't have to know of what type its parameters are when you create the string.
I tried to find similar approach in Swift, but what I found out was something like the following format:
"String %d formatted %d"
which requires you to format the string with String(format: , parameters). This is not good because you would also have to know parameter types when declaring the string.
Is there a similar approach in Swift where I wouldn't have to know the parameter types?
Use this one:
let printfOutput = String(format:"%# %2.2d", "string", 2)
It's the same as printf or the Obj-C formatting.
You can also mix it in this way:
let parm = "string"
let printfOutput = String(format:"\(parm) %2.2d", 2)
Edit: Thanks to MartinR (he knows it all ;-)
Be careful when mixing string interpolation and formatting. String(format:"\(parm) %2.2d", 2) will crash if parm contains a percent character. In (Objective-)C, the clang compiler will warn you if a format string is not a string literal.
This gives some room for hacking:
let format = "%#"
let data = "String"
let s = String(format: "\(format)", data) // prints "String"
In contrast to Obj-C which parses the format string at compile time, Swift does not do that and just interprets it at runtime.
In Swift, types need to conform to the CustomStringConvertible protocol in order to be used inside strings. This is also a requirement for the types used in string interpolation like this:
"Integer value \(intVal) and double value \(doubleVal)"
When you understand the CustomStringConvertible, you can create your own function to fulfill your needs. The following function formats the string based on the given arguments and prints it. It uses {} as a placeholder for the argument, but you can change it to anything you want.
func printWithArgs(string: String, argumentPlaceHolder: String = "{}", args: CustomStringConvertible...) {
var formattedString = string
// Get the index of the first argument placeholder
var nextPlaceholderIndex = string.range(of: argumentPlaceHolder)
// Index of the next argument to use
var nextArgIndex = 0
// Keep replacing the next placeholder as long as there's more placeholders and more unused arguments
while nextPlaceholderIndex != nil && nextArgIndex < args.count {
// Replace the argument placeholder with the argument
formattedString = formattedString.replacingOccurrences(of: argumentPlaceHolder, with: args[nextArgIndex].description, options: .caseInsensitive, range: nextPlaceholderIndex)
// Get the next argument placeholder index
nextPlaceholderIndex = formattedString.range(of: argumentPlaceHolder)
nextArgIndex += 1
}
print(formattedString)
}
printWithArgs(string: "First arg: {}, second arg: {}, third arg: {}", args: "foo", 4.12, 100)
// Prints: First arg: foo, second arg: 4.12, third arg: 100
Using a custom implementation allows you to have more control over it and tweak its behavior. For example, if you wanted to, you could modify this code to display the same argument multiple times using placeholders like {1} and {2}, you could fill the arguments in a reversed order, etc.
For more information about string interpolation in Swift: https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html#//apple_ref/doc/uid/TP40014097-CH7-ID292
Is there anyway to use a string literal as an argument to a function within a println statement.
func greetings(name: String) -> String {
return "Greetings \(name)!"
}
What I was trying to do: (I tried escaping the quotes around Earthling.)
println("OUTPUT: \(greetings("Earthling"))")
You can alternatively do this:
let name = "Earthling"
println("OUTPUT: \(greetings(name))")
And this works too:
println(greetings("Earthling"))
I tried escaping the quotes in the first example but with no luck, its not super important as its only a test, I was just curious if there was a way to do this, using a function call with a string literal as an argument within a print or println statement that contains other text.
From the Apple docs:
The expressions you write inside parentheses within an interpolated
string cannot contain an unescaped double quote (") or backslash (\),
and cannot contain a carriage return or line feed.
The problem is of course not with println but with the embedding of expressions with quotes in string literals.
Thus
let b = false
let s1 = b ? "is" : "isn't"
let s2 = "it \(b ? "is" : "isn't")" // won't compile
However NSLog as a one-liner'' works quite well here
NSLog("it %#", b ? "is" : "isn't")
Note %#, not %s. Try the latter in a playground to see why.