I am having a String that i would like to convert to Boolean Below is how the string looks like
String isValid = "false";
The String isValid can either be true or false
Is there a way i can directly convert this String isValid to Boolean. I have tried Sample questions and solutions but they are just converting Strings which are hard coded, for example most of the answers are just when the string is true
On top of my head, you can create an extension method for string data-type for your own need with all sorts of requirements checks and custom exceptions to beautify your desired functionalities. Here is an example:
import 'package:test/expect.dart';
void main(List<String> args) {
String isValid = "true";
print(isValid.toBoolean());
}
extension on String {
bool toBoolean() {
print(this);
return (this.toLowerCase() == "true" || this.toLowerCase() == "1")
? true
: (this.toLowerCase() == "false" || this.toLowerCase() == "0"
? false
: throwsUnsupportedError);
}
}
Here, in this example, I've created a variable named isValid in the main() method, which contains a string value. But, look closely at how I've parsed the string value to a bool value using the power with extension declared just a few lines below.
Same way, you can access the newly created string-extension method toBoolean() from anywhere. Keep in mind, if you're not in the same file where the toBoolean() extension is created, don't forget to import the proper reference.
Bonus tips:
You can also access toBoolean() like this,
bool alternateValidation = "true".toBoolean();
Happy coding 😊
This example can work for you, either if is false or true:
String isValid = "true";
bool newBoolValue = isValid.toLowerCase() != "false";
print(newBoolValue);
You can use extensions like this
bool toBoolean() {
String str = this!;
return str != '0' && str != 'false' && str != '';
}
First of All
You should make the string to lowercase to prevent check the string twice
then you can check if the string equal "true" or not and save the result to bool variable as below:
String isValidString = "false"; // the boolean inside string
bool isValid = isValidString.toLowerCase() == 'true'; // check if true after lowercase
print("isValid=$isValid"); // print the result
I opened a PR for this question, I believe that in the future it will be possible to do something native.
void main() {
print(bool.parse("true")); // true
print(bool.parse("false")); //false
print(bool.parse("TRUE")); // FormatException
print(bool.parse("FALSE")); //FormatException
print(bool.parse("True", caseSensitive: false)); // true
print(bool.parse("False", caseSensitive: false)); // false
if(bool.parse("true")){
//code..
}
}
Reference
https://github.com/dart-lang/sdk/pull/51026
Related
I making fun increase, decrease for item count. I want make count.text plus "T" Character. when I tried to make code like this.
error code: java.lang.NumberFormatException: For input string: "1T"
How can I solve this problem? Any one can help??
fun increaseInteger() {
var count = findViewById<TextView>(R.id.integer_number)
count.text=intent.getStringExtra("case")+"T"
var countResult = parseInt(intent.getStringExtra("case")+"T")
var countValue = countResult+1
if (countValue >= 1 && !decrease.isEnabled) { decrease.isEnabled = true}
intent.putExtra("result",countValue)
display(countValue)
}
fun decreaseInteger() {
var count = findViewById<TextView>(R.id.integer_number)
count.text=intent.getStringExtra("case")+"T"
var countResult = parseInt(intent.getStringExtra("case")+"T")
var countValue = countResult-1
if (countValue <= 1) {decrease.isEnabled = false }
intent.putExtra("result",countValue)
display(countValue)
}
The API is pretty straightforward:
"123".toInt() // returns 123 as Int
"123T".toInt() // throws NumberFormatException
"123".toIntOrNull() // returns 123 Int?
"123T".toIntOrNull() // returns null as Int?
So if you know your input might not be parseable to an Int, you can use toIntOrNull which will return null if the value was not parseable. It allows to use further nullability tools the language offers, e.g.:
input.toIntOrNull() ?: throw IllegalArgumentException("$input is not a valid number")
(This example uses the elvis operator to handle the undesired null response of toIntOrNull, the alternative would involve a try/catch around toInt)
You can use these
val str = "12345"
val str_new = "12345B"
str.toInt() // returns 123 as Int
str_new.toInt() // throws NumberFormatException
str.toIntOrNull() // returns 123 Int?
str_new.toIntOrNull() // returns null as Int?
I am trying to use a predicate to search an array of dictionary objects for a string value (from a searchController). I am not getting any partial string matches. I need to search through many key-values for a match, so I am doing it as written in the code below.
My problem is that if I search: "Orida"
I am not Finding: "Florida"
I believe I have the Predicate set correctly...
self.filteredData.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[cd] %#", self.searchController.searchBar.text!)
let array = (self.airportData as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredData = array as! [Dictionary<String, String>]
It is working correctly if I type the exact matching string that appears in any Value of the dictionary, but not if I search for a partial match...
This isn't a duplicate post - all of the existing posts about this that I've found either aren't searching multiple values (like multiple key-values in my dictionary) or are using the contains() method on strings themselves.
Update
I have tried the answer suggested below using filter:
let searchPredicate = NSPredicate(format: "SELF CONTAINS[cd] %#", searchController.searchBar.text!)
let array = (self.airportData as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredData = self.airportData.filter({(item: String) -> Bool in
var stringMatch = item.lowercaseString.rangeOfString(self.searchController.searchBar.text!)
return stringMatch != nil ? true : false
I get the following error:
'(String) -> Bool' is not convertible to '([String : String]) -> Bool'
I'm confused about how to get this to handle the dictionary of strings properly.
self.filteredData = self.airportData.filter({(item: String) -> Bool in
var stringMatch = item.lowercaseString.rangeOfString(self.searchController.searchBar.text!)
return stringMatch != nil ? true : false
})
Try to do this using the swift filter method on your array instead.
After a lot of advice from #pbush25, I was able to figure out an answer. It isn't exactly what I wanted, but it works. I was hoping to avoid specifying all the keys in the dictionary that I wanted to search the values of, but it ended up being the only way I could figure out to make it work. I would prefer to use the array.filter, but I couldn't figure out how to get that closure to cast as the right kind of array.
Functioning code:
let startCount = searchController.searchBar.text!.length
delay(1) {
if self.searchController.searchBar.text!.length >= 3 && self.searchController.searchBar.text!.length == startCount{
self.view.addSubview(self.progressHud)
self.appDel.backgroundThread(background: {
self.filteredData.removeAll(keepCapacity: false)
let searchText = self.searchController.searchBar.text!.lowercaseString
self.filteredData = self.airportData.filter{
if let ident = $0["ident"] {
if ident.lowercaseString.rangeOfString(searchText) != nil {
return true
}
}
if let name = $0["name"] {
if name.lowercaseString.rangeOfString(searchText) != nil {
return true
}
}
if let city = $0["municipality"] {
if city.lowercaseString.rangeOfString(searchText) != nil {
return true
}
}
return false
}
},
completion: {
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
self.progressHud.removeFromSuperview()
}
});
}
}
I am trying to validate a form to make sure the user has entered an integer number and not a string. I can check if the number is an integer as follows:
var possibleNumber = timeRetrieved.text
convertedNumber = possibleNumber.toInt()
// convertedNumber is inferred to be of type "Int?", or "optional Int"
if convertedNumber != nil {
println("It's a number!")
totalTime = convertedNumber!
}
My problem is I want to make sure the user has not entered any text, doubles etc. I only want integer numbers. The following code does not work because it evaluates true if the variable is an integer. What code should I use to evaluate if variable is not an integer?
if convertedNumber != nil {
let alertController = UIAlertController(title: "Validation Error", message: "You must enter an integer number!", preferredStyle: .Alert)
let alertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler: {(alert : UIAlertAction!) in
alertController.dismissViewControllerAnimated(true, completion: nil)
})
alertController.addAction(alertAction)
presentViewController(alertController, animated: true, completion: nil)
Swift 2 changes this: as both Int("abc") and Int("0") return 0, integer conversion can't be used. You could use this:
class Validation {
static func isStringNumerical(string : String) -> Bool {
// Only allow numbers. Look for anything not a number.
let range = string.rangeOfCharacterFromSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)
return (range == nil)
}
}
It uses a decimalDigitCharacterSet, and can be changed to use whatever character set you want.
func testIsStringNumerical() {
XCTAssertEqual(SignUpLoyaltyViewController.isStringNumerical("123"), true)
XCTAssertEqual(SignUpLoyaltyViewController.isStringNumerical(""), true)
XCTAssertEqual(SignUpLoyaltyViewController.isStringNumerical("12AA"), false)
XCTAssertEqual(SignUpLoyaltyViewController.isStringNumerical("123.4"), false)
}
This is dramatically faster than the Regex answer. (2000 runs, 0.004s vs regex 0.233s)
If the number the user has entered is not an integer, convertedNumber will be nil. Just add an else clause in which you can show the alert.
Int initializer
This works in Swift 2.2 and above. It is based on Minhal Khan's answer which illustrates that Int has an initializer with this signature: init?(_ text: String, radix: Int = default). Since radix has a default value, it can be left out. *more info on this initializer is found here.
var totalTime: Int?
let possibleInt = timeRetrieved.text ?? ""
if let convertedNumber = Int(possibleInt) {
print("'\(possibleInt)' is an Int")
totalTime = convertedNumber
}
else {
print("'\(possibleInt)' is not an Int")
}
print("totalTime: '\(totalTime)'")
Note: I assumed timeRetrieved is a UITextField. The UITextField text property is an optional string (though programmatically not allowed to be nil). Therefore, the compiler requires it be unwrapped. I used the nil coalescing operator (??) to substitute a nil for empty string which does not yield an integer as desired. Here's a post that discusses the optionality of UITextfield.text.
What i had done was get the value and check if it could convert it, works for me
var enteredText = Int(textfield.text)
if enteredText == nil{
//String entered
}
else{
//Int entered
}
Based on #Graham Perks answer a Swift 3 Version as string extension:
extension String
{
var isNumeric: Bool
{
let range = self.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted)
return (range == nil)
}
}
Usage:
"123".isNumeric // true
"abc".isNumeric // false
I really recommend using a REGEX, I was recently trying to validate 10 digit phone numbers using if let _ = Int(stringToTest)... and on 32 bit hardware, I faced range issues.
func validate(value: String) -> Bool {
let PHONE_REGEX = "\\d{10}"
let phoneTest = NSPredicate(format: "SELF MATCHES %#", PHONE_REGEX)
let result = phoneTest.evaluateWithObject(value)
if result == true {
log.info("'\(self.text!)' is a valid number.")
} else {
log.info("'\(self.text!)' is an invalid number.")
}
return result
}
I have the same problem like in this question:
How do I check if a string contains another string in Swift?
But now a few months later I wonder if it can be done without using NSString?
I nice and simple contains-method would be fine.
I searched the web and the documentation but I found nothing!
Same way, just with Swift syntax:
let string = "This is a test. This is only a test"
if string.rangeOfString("only") != nil {
println("yes")
}
For Swift 3.0
if str.range(of: "abc") != nil{
print("Got the string")
}
String actually provides a "contains" function through StringProtocol.
No extension whatsoever needed:
let str = "asdf"
print(str.contains("sd") ? "yep" : "nope")
https://developer.apple.com/reference/swift/string
https://developer.apple.com/documentation/swift/stringprotocol
If you want to check if your string matches a specific pattern, I can recommend the NSHipster article about NSRegularExpressions: http://nshipster.com/nsregularexpression/
I wrote an extension on String for SWIFT 3.0 so that i could simply call absoluteString.contains(string: "/kredit/")
extension String {
public func contains(string: String)-> Bool {
return self.rangeOfString(string) != nil
}
}
just to demonstrate the use of options.
var string = "This is a test. This is only a test. Not an Exam"
if string.range(of:"ex") != nil {
print("yes")
}
if string.range(of:"ex", options: String.CompareOptions.caseInsensitive) != nil {
print("yes")
}
In Dart, there is a convenience method for converting a String to an int:
int i = int.parse('123');
Is there something similar for converting String to bool?
bool b = bool.parse('true');
Bool has no methods.
var val = 'True';
bool b = val.toLowerCase() == 'true';
should be easy enough.
With recent Dart versions with extension method support the code could be made look more like for int, num, float.
extension BoolParsing on String {
bool parseBool() {
return this.toLowerCase() == 'true';
}
}
void main() {
bool b = 'tRuE'.parseBool();
print('${b.runtimeType} - $b');
}
See also https://dart.dev/guides/language/extension-methods
To the comment from #remonh87
If you want exact 'false' parsing you can use
extension BoolParsing on String {
bool parseBool() {
if (this.toLowerCase() == 'true') {
return true;
} else if (this.toLowerCase() == 'false') {
return false;
}
throw '"$this" can not be parsed to boolean.';
}
}
No. Simply use:
String boolAsString;
bool b = boolAsString == 'true';
You cannot perform this operation as you describe bool.parse('true') because Dart SDK is a lightweight as possible.
Dart SDK is not so unified as, for example, NET Framework where all basic system types has the following unification.
IConvertible.ToBoolean
IConvertible.ToByte
IConvertible.ToChar
IConvertible.ToDateTime
IConvertible.ToDecimal
IConvertible.ToDouble
IConvertible.ToInt16
IConvertible.ToInt32
IConvertible.ToInt64
IConvertible.ToSByte
IConvertible.ToSingle
IConvertible.ToString
IConvertible.ToUInt16
IConvertible.ToUInt32
IConvertible.ToUInt64
Also these types has parse method, including Boolean type.
So you cannot to do this in unified way. Only by yourself.
Actually yes, there is!
It's as simple as
bool.fromEnvironment(strValue, defaultValue: defaultValue);
Keep in mind that you may need to do strValue.toLowerCase()