-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change behaviour of .int
and .intValue
#735
Comments
I don't use .intValue only .int and when i need it to be forced I use .int! when you only use those two it pretty clear which one is optional. The thing is unless someone found something better than .optionalInt (.optionalInt! is kinda long an weird no much swifty) for optionals it's not gonna be worth to change. PS : I'm only a user so take my point considering it :) |
|
.int
and .intValue
.int
and .intValue
Why use For instance:
(Or |
Sigh, that's not what I meant. What I mean is that I would want to merge the functionality of |
I get what you mean, but what would be the return type of this computed variable? It can't be public var somethingInt : Int {
get {
if (canConvert()) {
return 2 //An int, as you want
}
return nil //Compilation error: Nil is incompatible with return type 'Int'
}
} Changing the function to return an Does that make sense? Did I miss something? |
Since you cant return an extension JSON {
public typealias IntValue = (value:Int, notNil:Bool)
public var intEx : IntValue {
get {
//let newSelf = self
if let intValue = self.int {
print("inside intvalue")
return (value: intValue, notNil: true)
}
return (value: 0, notNil: false)
}
}
}
//Ex:
let myInt = myJsonVar["myNumber1"].IntEx //myJsonVar["myNumber1"] returns 5
let myOtherInt = myJsonVar["myNumber2"].IntEx //myJsonVar["notANumber"] returns "abc"
print(myInt)
if myInt.notNil {
print(myInt.value)
}
print(myOtherInt)
if myOtherInt.notNil {
print(myOtherInt.value)
}
//would print:
(5, true)
5
(0, false) |
Okay, it proves more difficult to communicate my intention than I had anticipated. I'm going to try one more time to explain and then I'll give up. Right now public var int: Int? {
if case .number = self.type {
return self.rawNumber.intValue
} else {
return nil
}
} NOTE: This is NOT its real implementation, I'm simplifying things for the purpose of this demonstration.
And public var intValue: Int {
switch self.type {
case .string:
// try to convert string to int.
// if that's not possible return 0
case .number:
// return that number as an int
case .bool:
// convert bool to int and return
default:
return 0
}
} NOTE: This is NOT its real implementation, I'm simplifying things for the purpose of this demonstration.
So like I said, I want to merge these two features, like so: public var newInt: Int? {
switch self.type {
case .string:
// try to convert string to int.
// if that's not possible return nil
case .number:
// return that number as an int
case .bool:
// convert bool to int and return
default:
return nil
}
}
Since this new feature is, in my opinion, better than both And this could be applied to bool, and float, double, uint, etcetera. Please tell me you guys understand what I mean now. |
I get it, it seems like strings that can be converted to numbers do not work with If you want to modify the api, you can change the computed var public var number: NSNumber? {
get {
switch self.type {
case .Number, .Bool:
return self.rawNumber
// added .String case that mimics var numberValue, but returns nil
case .String:
let decimal = NSDecimalNumber(string: self.object as? String)
if decimal == NSDecimalNumber.notANumber() { // indicates parse error
return nil
}
return decimal
// end addition
default:
return nil
}
}
set {
self.object = newValue ?? NSNull()
}
} The only downside to the above changes is that calling here is an extension extension JSON {
public var trueInt: Int? {
get {
if let num = self.number as? NSDecimalNumber {
let intLong = num.longValue
if num == intLong {
return intLong
}
return nil
}
return self.number?.longValue
}
set {
if let newValue = newValue {
self.object = NSNumber(integer: newValue)
} else {
self.object = NSNull()
}
}
}
} |
I would like to see this happen. Here is a pull request which fixes this: #910. For some extra information, Android's core JSON class also does this. If the raw value is a string it tries to convert it to a double and cast it to an int. |
@kevinvanmierlo saw your comments and added some more unit tests to make sure that floats and ints also work. Had to add additional code to the Int type so that "3" would generate 3, while "3.14" would generate nil so that it behaves more like Swift typecasting. the intValue version would generate 3 and 0 for the same cases. |
@Causaelity Awesome! Although I wouldn't mind "3.14" generating a "3" (Android's core JSON class does the same). Would love to see your pull request merged! |
As I understand it, SwiftyJSON wants to allow for fuzzy types, because that's how javascript works too, right? I like that, but I don't like how that's implemented.
Right now,
.int
returns an optional int, which is nil if the value is not a real int. And.intValue
provides an int no matter what, which means is tries to convert other values to int values and if that's not possible then it returns a 0.The thing I don't like about
.intValue
is that if I get a0
back, that I don't know if the value wasn't a valid integer, or if the value was in fact a 0. I would like to have a feature that's a bit in between these two features. I would like something that tries to convert the value to an int, and if that's not possible, to return a nil.Does anyone else like this idea?
The text was updated successfully, but these errors were encountered: