compare double values in swift - ios

I want to compare two double values in swift
var first_value = 10.20
var second_value = 20.30
if first_value > second_value
println("some statement")
how can we compare this type of stuff..

The first thing you learn in Swift is {} are mandatory for all if, if else, and else statements.
So, your code should look like this:
var first_value = 10.20
var second_value = 20.30
if first_value > second_value {
print("first_value is greater than second_value")
}
else {
print("first_value is not greater than second_value ")
}

You should'n use '>', '<' and '=' signs to compare float or double.
Especially for comparison of close values (float i = 0.56; float j = 0.56; time to time you'll get wrong results in comparison i == j).
You should use constants from float.h, as it is described here.

Comparing 2 double numbers using binary signs <,>, == is not entirely correct because of the device of this type of data in the computer's memory. For example, compare 2 double values:
var a: Double = 10.0
var b: Double = 10.0
print(a == b) // false
So, you need determine decimal place precision for comparison.
public extension Double {
func greaterThan(_ value: Double, precise: Int) -> Bool {
let denominator: Double = pow(10.0, Double(precise))
let maxDiff: Double = 1 / denominator
let realDiff: Double = self - value
if fabs(realDiff) >= maxDiff, realDiff > 0 {
return true
} else {
return false
}
}
func greaterThanOrEqual(_ value: Double, precise: Int) -> Bool {
let denominator: Double = pow(10.0, Double(precise))
let maxDiff: Double = 1 / denominator
let realDiff: Double = self - value
if fabs(realDiff) >= maxDiff, realDiff >= 0 {
return true
} else if fabs(realDiff) <= maxDiff {
return true
} else {
return false
}
}
func lessThan(_ value: Double, precise: Int) -> Bool {
let denominator: Double = pow(10.0, Double(precise))
let maxDiff: Double = 1 / denominator
let realDiff: Double = self - value
if fabs(realDiff) >= maxDiff, realDiff < 0 {
return true
} else {
return false
}
}
func lessThanOrEqual(_ value: Double, precise: Int) -> Bool {
let denominator: Double = pow(10.0, Double(precise))
let maxDiff: Double = 1 / denominator
let realDiff: Double = self - value
if fabs(realDiff) >= maxDiff, realDiff <= 0 {
return true
} else if fabs(realDiff) <= maxDiff {
return true
} else {
return false
}
}
func equal(_ value: Double, precise: Int) -> Bool {
let denominator: Double = pow(10.0, Double(precise))
let maxDiff: Double = 1 / denominator
let realDiff: Double = self - value
if fabs(realDiff) <= maxDiff {
return true
} else {
return false
}
}
}
Usage:
var a: Double = 10.0
var b: Double = 10.0
print(a.equal(a, precise: 3)) // true

Updated Ans
var first_value = 10.20
var second_value = 20.30
if first_value.isLess(than: second_value) {
print("first_value is not greater than second_value ")
} else {
print("first_value is greater than second_value ")
}

Please read intro chapters to basic swift syntax:
var first_value = 10.20
var second_value = 20.30
if first_value > second_value {
println("some statement")
}

Related

Jaro Winkler distance in Objective-C or Swift

I need to do fuzzy comparison of a large number of strings and am looking at Jaro-Winkler which respects differences in the order of letters. Is anyone aware of a way to do this in Objective-C or Swift either using Jaro-Winkler or some method native to IOS?
Thanks for any recommendations or suggestions.
I took an inspiration in Apache Commons and rewritten it to Swift:
extension String {
static func jaroWinglerDistance(_ first: String, _ second: String) -> Double {
let longer = Array(first.count > second.count ? first : second)
let shorter = Array(first.count > second.count ? second : first)
let (numMatches, numTranspositions) = jaroWinklerData(longer: longer, shorter: shorter)
if numMatches == 0 {
return 0
}
let defaultScalingFactor = 0.1;
let percentageRoundValue = 100.0;
let jaro = [
numMatches / Double(first.count),
numMatches / Double(second.count),
(numMatches - numTranspositions) / numMatches
].reduce(0, +) / 3
let jaroWinkler: Double
if jaro < 0.7 {
jaroWinkler = jaro
} else {
let commonPrefixLength = Double(commonPrefix(first, second).count)
jaroWinkler = jaro + Swift.min(defaultScalingFactor, 1 / Double(longer.count)) * commonPrefixLength * (1 - jaro)
}
return round(jaroWinkler * percentageRoundValue) / percentageRoundValue
}
private static func commonPrefix(_ first: String, _ second: String) -> String{
return String(
zip(first, second)
.prefix { $0.0 == $0.1 }
.map { $0.0 }
)
}
private static func jaroWinklerData(
longer: Array<Character>,
shorter: Array<Character>
) -> (numMatches: Double, numTranspositions: Double) {
let window = Swift.max(longer.count / 2 - 1, 0)
var shorterMatchedChars: [Character] = []
var longerMatches = Array<Bool>(repeating: false, count: longer.count)
for (offset, shorterChar) in shorter.enumerated() {
let windowRange = Swift.max(offset - window, 0) ..< Swift.min(offset + window + 1, longer.count)
if let matchOffset = windowRange.first(where: { !longerMatches[$0] && shorterChar == longer[$0] }) {
shorterMatchedChars.append(shorterChar)
longerMatches[matchOffset] = true
}
}
let longerMatchedChars = longerMatches
.enumerated()
.filter { $0.element }
.map { longer[$0.offset] }
let numTranspositions: Int = zip(shorterMatchedChars, longerMatchedChars)
.lazy
.filter { $0.0 != $0.1 }
.count / 2
return (
numMatches: Double(shorterMatchedChars.count),
numTranspositions: Double(numTranspositions)
)
}
}
Tested by the examples found in the original code:
print(String.jaroWinglerDistance("", ""))
print(String.jaroWinglerDistance("", "a"))
print(String.jaroWinglerDistance("aaapppp", ""))
print(String.jaroWinglerDistance("frog", "fog"))
print(String.jaroWinglerDistance("fly", "ant"))
print(String.jaroWinglerDistance("elephant", "hippo"))
print(String.jaroWinglerDistance("hippo", "elephant"))
print(String.jaroWinglerDistance("hippo", "zzzzzzzz"))
print(String.jaroWinglerDistance("hello", "hallo"))
print(String.jaroWinglerDistance("ABC Corporation", "ABC Corp"))
print(String.jaroWinglerDistance("D N H Enterprises Inc", "D & H Enterprises, Inc."))
print(String.jaroWinglerDistance("My Gym Children's Fitness Center", "My Gym. Childrens Fitness"))
print(String.jaroWinglerDistance("PENNSYLVANIA", "PENNCISYLVNIA"))
I have also found another implementation of String similarity functions in github.

How can split from string to array by chunks of given size

I want to split string by chunks of given size 2
Example :
String "1234567" and output should be ["12", "34", "56","7"]
You can group your collection elements (in this case Characters) every n elements as follow:
extension Collection {
func unfoldSubSequences(limitedTo maxLength: Int) -> UnfoldSequence<SubSequence,Index> {
sequence(state: startIndex) { start in
guard start < self.endIndex else { return nil }
let end = self.index(start, offsetBy: maxLength, limitedBy: self.endIndex) ?? self.endIndex
defer { start = end }
return self[start..<end]
}
}
func subSequences(of n: Int) -> [SubSequence] {
.init(unfoldSubSequences(limitedTo: n))
}
}
let numbers = "1234567"
let subSequences = numbers.subSequences(of: 2)
print(subSequences) // ["12", "34", "56", "7"]
edit/update:
If you would like to append the exceeding characters to the last group:
extension Collection {
func unfoldSubSequencesWithTail(lenght: Int) -> UnfoldSequence<SubSequence,Index> {
let n = count / lenght
var counter = 0
return sequence(state: startIndex) { start in
guard start < endIndex else { return nil }
let end = index(start, offsetBy: lenght, limitedBy: endIndex) ?? endIndex
counter += 1
if counter == n {
defer { start = endIndex }
return self[start...]
} else {
defer { start = end }
return self[start..<end]
}
}
}
func subSequencesWithTail(n: Int) -> [SubSequence] {
.init(unfoldSubSequencesWithTail(lenght: n))
}
}
let numbers = "1234567"
let subSequencesWithTail = numbers.subSequencesWithTail(n: 2)
print(subSequencesWithTail) // ["12", "34", "567"]
var testString = "abcdefghijklmnopqrstu"
var startingPoint: Int = 0
var substringLength: Int = 1
var substringArray = [AnyHashable]()
for i in 0..<(testString.count ?? 0) / substringLength {
var substring: String = (testString as NSString).substring(with: NSRange(location: startingPoint, length: substringLength))
substringArray.append(substring)
startingPoint += substringLength
}
print("\(substringArray)")
OutPut :
(
a,
b,
c,
d,
e,
f,
g,
h,
i,
j,
k,
l,
m,
n,
o,
p,
q,
r,
s,
t,
u
)
try this
func SplitString(stringToBeSplitted:String, By:Int) -> [String]
{
var newArray = [String]()
var newStr = String()
for char in stringToBeSplitted
{
newStr += String(char)
if newStr.count == By
{
newArray.append(newStr)
newStr = ""
}
}
return newArray
}
Swift 5
extension Array {
func chunks(size: Int) -> [[Element]] {
return stride(from: 0, to: count, by: size).map {
Array(self[$0 ..< Swift.min($0 + size, count)])
}
}
}
extension String {
func chunks(size: Int) -> [String] {
map { $0 }.chunks(size: size).compactMap { String($0) }
}
}
let s = "1234567"
print(s.chunks(size: 2)) // ["12", "34", "56", "7"]
extension String {
func split(len: Int) -> [String] {
var currentIndex = 0
var array = [String]()
let length = self.characters.count
while currentIndex < length {
let startIndex = self.startIndex.advancedBy(currentIndex)
let endIndex = startIndex.advancedBy(len, limit: self.endIndex)
let substr = self.substringWithRange(Range(start: startIndex, end: endIndex))
array.append(substr)
currentIndex += len
}
return array
}
}
"123456789".split(2)
//output: ["12", "34", "56", "78", "9"]
I have write one method in objective c as below,
-(NSMutableArray*)splitString : (NSString*)str withRange : (int)range{
NSMutableArray *arr = [[NSMutableArray alloc]init];
NSMutableString *mutableStr = [[NSMutableString alloc]initWithString:str];
int j = 0;
int counter = 0;
for (int i = 0; i < str.length; i++) {
j++;
if (range == j) {
j = 0;
if (!(i == str.length - 1)) {
[mutableStr insertString:#"$" atIndex:i+1+counter];
}
counter++;
}
}
arr = (NSMutableArray*)[mutableStr componentsSeparatedByString:#"$"];
NSLog(#"%#",arr);
return arr;
}
You can call this method like,
[self splitString:#"123456" withRange:2];
and result will be,
(
12,
34,
56
)
You can also try below code:
var arrStr: [Substring] = []
let str = "1234567"
var i = 0
while i < str.count - 1 {
let index = str.index(str.startIndex, offsetBy: i)
//Below line gets current index and advances by 2
let substring = str[index..<str.index(index, offsetBy: 2)]
arrStr.append(substring)
i += 2
}
if str.count % 2 == 1 {
arrStr.append(str.suffix(1))
}
print(arrStr)
There's a stupid way, you can think about the rules of the data model.
var strOld = "123456"
print("The original string:\(strOld)")
strOld.insert("、", at: strOld.index(before: strOld.index(strOld.startIndex, offsetBy: 3)))
strOld.insert("、", at: strOld.index(before: strOld.index(strOld.startIndex, offsetBy: 6)))
print("After inserting:\(strOld)")
let str = strOld
let splitedArray = str.components(separatedBy: "、")
print("After the split of the array:\(splitedArray)")
let splitedArrayOther = str.split{$0 == "、"}.map(String.init)
print("After break up the array (method 2):\(splitedArrayOther)")
The results:
The original string:123456
After inserting:12、34、56
After the split of the array:["12", "34", "56"]
After break up the array (method 2):["12", "34", "56"]
Here's a short (and clean) solution, thanks to recursion:
extension Collection {
func chunks(ofSize size: Int) -> [SubSequence] {
// replace this by `guard count >= size else { return [] }`
// if you want to omit incomplete chunks
guard !isEmpty else { return [] }
return [prefix(size)] + dropFirst(size).chunks(ofSize: size)
}
}
The recursion should not pose a performance problem, as Swift has support for tail call optimization.
Also if Swift arrays are really fast when it comes to prepending or appending elements (like the Objective-C ones are), then the array operations should be fast.
Thus you get both fast and readable code (assuming my array assumptions are true).

Swift 2.0 Format 1000's into a friendly K's

I'm trying to write a function to present thousands and millions into K's and M's
For instance:
1000 = 1k
1100 = 1.1k
15000 = 15k
115000 = 115k
1000000 = 1m
Here is where I got so far:
func formatPoints(num: Int) -> String {
let newNum = String(num / 1000)
var newNumString = "\(num)"
if num > 1000 && num < 1000000 {
newNumString = "\(newNum)k"
} else if num > 1000000 {
newNumString = "\(newNum)m"
}
return newNumString
}
formatPoints(51100) // THIS RETURNS 51K instead of 51.1K
How do I get this function to work, what am I missing?
extension Int {
var roundedWithAbbreviations: String {
let number = Double(self)
let thousand = number / 1000
let million = number / 1000000
if million >= 1.0 {
return "\(round(million*10)/10)M"
}
else if thousand >= 1.0 {
return "\(round(thousand*10)/10)K"
}
else {
return "\(self)"
}
}
}
print(11.roundedWithAbbreviations) // "11"
print(11111.roundedWithAbbreviations) // "11.1K"
print(11111111.roundedWithAbbreviations) // "11.1 M"
func formatPoints(num: Double) ->String{
let thousandNum = num/1000
let millionNum = num/1000000
if num >= 1000 && num < 1000000{
if(floor(thousandNum) == thousandNum){
return("\(Int(thousandNum))k")
}
return("\(thousandNum.roundToPlaces(1))k")
}
if num > 1000000{
if(floor(millionNum) == millionNum){
return("\(Int(thousandNum))k")
}
return ("\(millionNum.roundToPlaces(1))M")
}
else{
if(floor(num) == num){
return ("\(Int(num))")
}
return ("\(num)")
}
}
extension Double {
/// Rounds the double to decimal places value
func roundToPlaces(places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return round(self * divisor) / divisor
}
}
The updated code should now not return a .0 if the number is whole. Should now output 1k instead of 1.0k for example. I just checked essentially if double and its floor were the same.
I found the double extension in this question:
Rounding a double value to x number of decimal places in swift
The extension below does the following-
Will display number 10456 as 10.5k and 10006 as 10k (will not show the .0 decimals).
Will do the exact above for millions and format it i.e. 10.5M and 10M
Will format thousands upto 9999 in currency format i.e. with a comma like 9,999
extension Double {
var kmFormatted: String {
if self >= 10000, self <= 999999 {
return String(format: "%.1fK", locale: Locale.current,self/1000).replacingOccurrences(of: ".0", with: "")
}
if self > 999999 {
return String(format: "%.1fM", locale: Locale.current,self/1000000).replacingOccurrences(of: ".0", with: "")
}
return String(format: "%.0f", locale: Locale.current,self)
}
}
Usage:
let num: Double = 1000001.00 //this should be a Double since the extension is on Double
let millionStr = num.kmFormatted
print(millionStr)
Prints 1M
And here it is in action-
To add to the answers, here's a Swift 4.X version of this using a loop to easily add/remove units if necessary:
extension Double {
var shortStringRepresentation: String {
if self.isNaN {
return "NaN"
}
if self.isInfinite {
return "\(self < 0.0 ? "-" : "+")Infinity"
}
let units = ["", "k", "M"]
var interval = self
var i = 0
while i < units.count - 1 {
if abs(interval) < 1000.0 {
break
}
i += 1
interval /= 1000.0
}
// + 2 to have one digit after the comma, + 1 to not have any.
// Remove the * and the number of digits argument to display all the digits after the comma.
return "\(String(format: "%0.*g", Int(log10(abs(interval))) + 2, interval))\(units[i])"
}
}
Examples:
$ [1.5, 15, 1000, 1470, 1000000, 1530000, 1791200000].map { $0.shortStringRepresentation }
[String] = 7 values {
[0] = "1.5"
[1] = "15"
[2] = "1k"
[3] = "1.5k"
[4] = "1M"
[5] = "1.5M"
[6] = "1791.2M"
}
Some Change in Answer(For Int and correct for million):
func formatPoints(num: Int) ->String{
let thousandNum = num/1000
let millionNum = num/1000000
if num >= 1000 && num < 1000000{
if(thousandNum == thousandNum){
return("\(thousandNum)k")
}
return("\(thousandNum)k")
}
if num > 1000000{
if(millionNum == millionNum){
return("\(millionNum)M")
}
return ("\(millionNum)M")
}
else{
if(num == num){
return ("\(num)")
}
return ("\(num)")
}
}
For swift 4.0. its work completely fine and answer based on #user3483203
Function for convert Double value to String
func formatPoints(num: Double) ->String{
var thousandNum = num/1000
var millionNum = num/1000000
if num >= 1000 && num < 1000000{
if(floor(thousandNum) == thousandNum){
return("\(Int(thousandNum))k")
}
return("\(thousandNum.roundToPlaces(places: 1))k")
}
if num > 1000000{
if(floor(millionNum) == millionNum){
return("\(Int(thousandNum))k")
}
return ("\(millionNum.roundToPlaces(places: 1))M")
}
else{
if(floor(num) == num){
return ("\(Int(num))")
}
return ("\(num)")
}
}
Make one Double extension
extension Double {
/// Rounds the double to decimal places value
mutating func roundToPlaces(places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return Darwin.round(self * divisor) / divisor
}
}
Usage of above function
UILABEL.text = formatPoints(num: Double(310940)!)
Output :
Here is my approach to it.
extension Int {
func shorted() -> String {
if self >= 1000 && self < 10000 {
return String(format: "%.1fK", Double(self/100)/10).replacingOccurrences(of: ".0", with: "")
}
if self >= 10000 && self < 1000000 {
return "\(self/1000)k"
}
if self >= 1000000 && self < 10000000 {
return String(format: "%.1fM", Double(self/100000)/10).replacingOccurrences(of: ".0", with: "")
}
if self >= 10000000 {
return "\(self/1000000)M"
}
return String(self)
}
Below are some examples:
print(913.shorted())
print(1001.shorted())
print(1699.shorted())
print(8900.shorted())
print(10500.shorted())
print(17500.shorted())
print(863500.shorted())
print(1200000.shorted())
print(3010000.shorted())
print(11800000.shorted())
913
1K
1.6K
8.9K
10k
17k
863k
1.2M
3M
11M
Solution above (from #qlear) in Swift 3:
func formatPoints(num: Double) -> String {
var thousandNum = num / 1_000
var millionNum = num / 1_000_000
if num >= 1_000 && num < 1_000_000 {
if floor(thousandNum) == thousandNum {
return("\(Int(thousandNum))k")
}
return("\(thousandNum.roundToPlaces(1))k")
}
if num > 1_000_000 {
if floor(millionNum) == millionNum {
return "\(Int(thousandNum))k"
}
return "\(millionNum.roundToPlaces(1))M"
}
else{
if floor(num) == num {
return "\(Int(num))"
}
return "\(num)"
}
}
extension Double {
// Rounds the double to decimal places value
mutating func roundToPlaces(_ places : Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self.rounded() * divisor) / divisor
}
}
I have converted #AnBisw's answer to use switch (build time friendly):
extension Double {
var kmFormatted: String {
switch self {
case ..<1_000:
return String(format: "%.0f", locale: Locale.current, self)
case 1_000 ..< 999_999:
return String(format: "%.1fK", locale: Locale.current, self / 1_000).replacingOccurrences(of: ".0", with: "")
default:
return String(format: "%.1fM", locale: Locale.current, self / 1_000_000).replacingOccurrences(of: ".0", with: "")
}
}
}
Based on the solution from #qlear.
I've noticed that if the number was exactly 1000000, it would return 1000000 unformatted.
So I've added that into the function. I also included negative values.. since not everyone is always making a profit!
func formatPoints(num: Double) ->String{
let thousandNum = num/1000
let millionNum = num/1000000
if num > 0
{
if num >= 1000 && num < 1000000{
if(floor(thousandNum) == thousandNum){
return("\(Int(thousandNum))k")
}
return("\(round1(thousandNum, toNearest: 0.01))k")
}
if num > 1000000{
if(floor(millionNum) == millionNum){
return("\(Int(thousandNum))k")
}
return ("\(round1(millionNum, toNearest: 0.01))M")
}
else if num == 1000000
{
return ("\(round1(millionNum, toNearest: 0.01))M")
}
else{
if(floor(num) == num){
return ("\(Int(num))")
}
return ("\(round1(num, toNearest: 0.01))")
}
}
else
{
if num <= -1000 && num > -1000000{
if(floor(thousandNum) == thousandNum){
return("\(Int(thousandNum))k")
}
return("\(round1(thousandNum, toNearest: 0.01))k")
}
if num < -1000000{
if(floor(millionNum) == millionNum){
return("\(Int(thousandNum))k")
}
return ("\(round1(millionNum, toNearest: 0.01))M")
}
else if num == -1000000
{
return ("\(round1(millionNum, toNearest: 0.01))M")
}
else{
if(floor(num) == num){
return ("\(Int(num))")
}
return ("\(round1(num, toNearest: 0.01))")
}
}
}
And the number extension of course:
extension Double {
/// Rounds the double to decimal places value
func round1(_ value: Double, toNearest: Double) -> Double {
return Darwin.round(value / toNearest) * toNearest
}
}
This solution utilises ByteCountFormatter, but for any big number abbreviation of any number type. Why this formatter written by Apple for bytes only remains unknown.
extension Numeric {
var abbreviated: String {
let bytesString = ByteCountFormatter.string(fromByteCount: (self as! NSNumber).int64Value, countStyle: .decimal)
let numericString = bytesString
.replacingOccurrences(of: "bytes", with: "")
.replacingOccurrences(of: "B", with: "") // removes B (bytes) in 'KB'/'MB'/'GB'
.replacingOccurrences(of: "G", with: "B") // replace G (Giga) to just B (billions)
return numericString.replacingOccurrences(of: " ", with: "")
}
}
Minor improvement to #chrisz answer, Swift-4 Doble extension - This works fine in all cases.
extension Double {
// Formatting double value to k and M
// 1000 = 1k
// 1100 = 1.1k
// 15000 = 15k
// 115000 = 115k
// 1000000 = 1m
func formatPoints() -> String{
let thousandNum = self/1000
let millionNum = self/1000000
if self >= 1000 && self < 1000000{
if(floor(thousandNum) == thousandNum){
return ("\(Int(thousandNum))k").replacingOccurrences(of: ".0", with: "")
}
return("\(thousandNum.roundTo(places: 1))k").replacingOccurrences(of: ".0", with: "")
}
if self > 1000000{
if(floor(millionNum) == millionNum){
return("\(Int(thousandNum))k").replacingOccurrences(of: ".0", with: "")
}
return ("\(millionNum.roundTo(places: 1))M").replacingOccurrences(of: ".0", with: "")
}
else{
if(floor(self) == self){
return ("\(Int(self))")
}
return ("\(self)")
}
}
/// Returns rounded value for passed places
///
/// - parameter places: Pass number of digit for rounded value off after decimal
///
/// - returns: Returns rounded value with passed places
func roundTo(places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
if you want in lacs :
extension Int {
func shorted() -> String {
if self >= 1000 && self < 10000 {
return String(format: "%.1fK", Double(self/100)/10).replacingOccurrences(of: ".0", with: "")
}
if self >= 10000 && self < 100000 {
return "\(self/1000)k"
}
if self >= 100000 && self < 1000000 {
return String(format: "%.1fL", Double(self/10000)/10).replacingOccurrences(of: ".0", with: "")
}
if self >= 1000000 && self < 10000000 {
return String(format: "%.1fM", Double(self/100000)/10).replacingOccurrences(of: ".0", with: "")
}
if self >= 10000000 {
return "\(self/1000000)M"
}
return String(self)
}
}
Since we all more or less disagree
func FormatFriendly(num: Double) ->String {
var thousandNum = num/1000
var millionNum = num/1000000
if num >= 1000 && num < 1000000{
if(floor(thousandNum) == thousandNum){
return("\(Int(thousandNum))K").replacingOccurrences(of: ".0", with: "")
}
return("\(thousandNum.roundToPlaces(places: 1))K").replacingOccurrences(of: ".0", with: "")
}
if num >= 1000000{
//if(floor(millionNum) == millionNum){
//return("\(Int(thousandNum))K").replacingOccurrences(of: ".0", with: "")
//}
return ("\(millionNum.roundToPlaces(places: 1))M").replacingOccurrences(of: ".0", with: "")
}else {
if(floor(num) == num){
return ("\(Int(num))")
}
return ("\(num)")
}
}
extension Double {
/// Rounds the double to decimal places value
mutating func roundToPlaces(places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return Darwin.round(self * divisor) / divisor
}
}

How to parse string to NSTimeInterval

How to parse string value like 12:02:21.3213 to NSTimeInterval? NSDateComponentsFormatter, available since iOS8, supports only formatting, not parsing.
Here is how you can do it in Swift,
It works for values like
2:12:12,
02:01:23.123213
Swift 5 (by #Youstanzr):
extension String {
func convertToTimeInterval() -> TimeInterval {
guard self != "" else {
return 0
}
var interval:Double = 0
let parts = self.components(separatedBy: ":")
for (index, part) in parts.reversed().enumerated() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}
}
Swift 3 (by #Torre Lasley)
func parseDuration(_ timeString:String) -> TimeInterval {
guard !timeString.isEmpty else {
return 0
}
var interval:Double = 0
let parts = timeString.components(separatedBy: ":")
for (index, part) in parts.reversed().enumerated() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}
Swift 2
func parseDuration(timeString:String) -> NSTimeInterval {
guard !timeString.isEmpty else {
return 0
}
var interval:Double = 0
let parts = timeString.componentsSeparatedByString(":")
for (index, part) in parts.reverse().enumerate() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}
The solution provided by Bartosz Hernas worked for me, thank you!
For convenience, here it is for Swift 3:
func parseDuration(_ timeString:String) -> TimeInterval {
guard !timeString.isEmpty else {
return 0
}
var interval:Double = 0
let parts = timeString.components(separatedBy: ":")
for (index, part) in parts.reversed().enumerated() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}
Here is the Swift 5 version that I've made of #Bartosz answer
extension String {
func convertToTimeInterval() -> TimeInterval {
guard self != "" else {
return 0
}
var interval:Double = 0
let parts = self.components(separatedBy: ":")
for (index, part) in parts.reversed().enumerated() {
interval += (Double(part) ?? 0) * pow(Double(60), Double(index))
}
return interval
}
}

'String' is not convertible to 'Int' in Swift

In my adding function where answerLabel.text is it is giving me an error. It says 'String' is not convertible to 'Int' and I'm trying to get what I got from the secondStep2 and put in the parameters of my functions
//Adding Function
changingSignsLabel.text = "+"
let firstDenomInTextField:Double! = (firstDenominatorTextField.text as NSString).doubleValue
let firstNumInTextField:Double! = (firstNumeratorTextField.text as NSString).doubleValue
let firstWholeInTextField:Double! = (firstWholeNumberTextField.text as NSString).doubleValue
let secondDenomInTextField:Double! = (secondDenominatorTextField.text as NSString).doubleValue
let secondNumInTextField:Double! = (secondNumeratorTextField.text as NSString).doubleValue
let secondWholeInTextField:Double! = (secondWholeNumberTextField.text as NSString).doubleValue
var firstStep = firstDenomInTextField! * firstWholeInTextField! / firstDenomInTextField!
var secondStep = firstStep + firstNumInTextField! / firstDenomInTextField!
var thirdStep = secondDenomInTextField! * secondWholeInTextField! / secondDenomInTextField!
var fourthStep = thirdStep + secondNumInTextField! / secondDenomInTextField!
var calculatedAnswer = (secondStep + fourthStep)
answerLabel.hidden = false
var firstStep2 = calculatedAnswer / 1
var secondStep2 = "\(firstStep2 * 10 * 10)"
answerLabel.text = printSimplifiedFraction(Numerator: secondStep2)
My Function
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100)
{
var finalNumerator = numerator;
var finalDenominator = denominator;
var wholeNumbers:Int = numerator / denominator;
var remainder:Int = numerator % denominator;
//println("wholeNumbers = \(wholeNumbers), remainder = \(remainder)");
//println("\(denominator) % \(remainder) = \(denominator % remainder)");
if(remainder > 0)
{
// see if we can simply the fraction part as well
if(denominator % remainder == 0) // no remainder means remainder can be simplified further
{
finalDenominator = denominator / remainder;
finalNumerator = remainder / remainder;
}
else
{
finalNumerator = remainder;
finalDenominator = denominator;
}
}
if(wholeNumbers > 0 && remainder > 0)
{
// prints out whole number and fraction parts
println("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers) \(finalNumerator)/\(finalDenominator)");
}
else if (wholeNumbers > 0 && remainder == 0)
{
// prints out whole number only
println("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers)");
}
else
{
// prints out fraction part only
println("Simplified fraction of \(numerator)/\(denominator) = \(finalNumerator)/\(finalDenominator)");
}
}
My Question how do I get the function to accept my variable?
I believe this is what you want, first in your adding function it should be:
var firstStep2 = calculatedAnswer / 1
var secondStep2 = Int(firstStep2 * 10 * 10)
answerLabel.text = printSimplifiedFraction(Numerator: secondStep2)
Then your print... method should be changed like this (note that it's returning a String):
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100) -> String
{
// I haven't looked into this bit
...
if(wholeNumbers > 0 && remainder > 0)
{
return ("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers) \(finalNumerator)/\(finalDenominator)")
}
else if (wholeNumbers > 0 && remainder == 0)
{
return ("Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers)")
}
else
{
return ("Simplified fraction of \(numerator)/\(denominator) = \(finalNumerator)/\(finalDenominator)")
}
}
Also, looking through your code I think you can simplify the logic quite a bit (I've also converted to Integers as you said you wanted in the comments):
let firstDenomInTextField = firstDenominatorTextField.text.toInt()
let firstNumInTextField = firstNumeratorTextField.text.toInt()
let firstWholeInTextField = firstWholeNumberTextField.text.toInt()
let secondDenomInTextField = secondDenominatorTextField.text.toInt()
let secondNumInTextField = secondNumeratorTextField.text.toInt()
let secondWholeInTextField = secondWholeNumberTextField.text.toInt()
var firstStep = firstWholeInTextField! + firstNumInTextField! / firstDenomInTextField!
var secondStep = secondWholeInTextField! + secondNumInTextField! / secondDenomInTextField!
var calculatedAnswer = (firstStep + secondStep)
var numerator = Int(calculatedAnswer * 10 * 10)
answerLabel.text = printSimplifiedFraction(Numerator: numerator)
Try this:
var str:String = "abc"
var a:Int? = str.toInt()
if (a != nil) {
printSimplifiedFraction(Numerator: str!)
}
And add a return value to your function
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100) ->String {
var finalNumerator = numerator;
var finalDenominator = denominator;
var wholeNumbers:Int = numerator / denominator;
var remainder:Int = numerator % denominator;
if(remainder > 0)
{
// see if we can simply the fraction part as well
if(denominator % remainder == 0) // no remainder means remainder can be simplified further
{
finalDenominator = denominator / remainder;
finalNumerator = remainder / remainder;
}
else
{
finalNumerator = remainder;
finalDenominator = denominator;
}
}
var result:String = "Simplified fraction of \(numerator)/\(denominator) = ";
if(wholeNumbers > 0 && remainder > 0)
{
// prints out whole number and fraction parts
result += "\(wholeNumbers) \(finalNumerator)/\(finalDenominator)"
}
else if (wholeNumbers > 0 && remainder == 0)
{
// prints out whole number only
result += "\(wholeNumbers)"
}
else
{
// prints out fraction part only
result += "\(finalNumerator)/\(finalDenominator)"
}
println("\(result)")
return result
}
this printSimplifiedFraction is not returning any value, but you are assigning to the answerLabel.text, i think this is the problem.
If you want to assign a value which is returned form fuction, add return type to the fuction and return a value.
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100) -> String {
//add end of your function
return yourValue;
}
Check this link
In Your Code do like this
var secondStep2 = (firstStep2 * 10 * 10)
answerLabel.text = printSimplifiedFraction(Numerator: secondStep2)
func printSimplifiedFraction(Numerator numerator: Int, Denominator denominator: Int = 100) -> String
{
var finalNumerator = numerator;
var finalDenominator = denominator;
var wholeNumbers:Int = numerator / denominator;
var remainder:Int = numerator % denominator;
//println("wholeNumbers = \(wholeNumbers), remainder = \(remainder)");
//println("\(denominator) % \(remainder) = \(denominator % remainder)");
if(remainder > 0)
{
// see if we can simply the fraction part as well
if(denominator % remainder == 0) // no remainder means remainder can be simplified further
{
finalDenominator = denominator / remainder;
finalNumerator = remainder / remainder;
}
else
{
finalNumerator = remainder;
finalDenominator = denominator;
}
}
var returnValue :String
if(wholeNumbers > 0 && remainder > 0)
{
returnValue = "Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers) \(finalNumerator)/\(finalDenominator)"
}
else if (wholeNumbers > 0 && remainder == 0)
{
returnValue = "Simplified fraction of \(numerator)/\(denominator) = \(wholeNumbers)"
}
else
{
returnValue = "Simplified fraction of \(numerator)/\(denominator) = \(finalNumerator)/\(finalDenominator)"
}
return returnValue
}

Resources