Skip to content

Instantly share code, notes, and snippets.

@jmdoan1
Created August 24, 2018 20:17
Show Gist options
  • Save jmdoan1/fbb9101764db0ba9fd4987425f427efb to your computer and use it in GitHub Desktop.
Save jmdoan1/fbb9101764db0ba9fd4987425f427efb to your computer and use it in GitHub Desktop.
//
// DigitString.swift
// JDConvenienceKit
//
// Created by Justin Doan on 8/23/18.
// Copyright © 2018 Justin Doan. All rights reserved.
//
import Foundation
import UIKit
///Option to declare if your returned value should factor rounding or just truncate the value
enum digitStringOptions {
case truncated, rounded
}
///Takes an unknow value and converts to Double if possible
func genericToDouble<T>(_ genericVal: T) -> Double? {
switch genericVal {
case let x as CGFloat:
return Double(x)
case let x as Float:
return Double(x)
case let x as Double:
return Double(x)
case let x as Int:
return Double(x)
case let x as UInt:
return Double(x)
case let x as Int8:
return Double(x)
case let x as UInt8:
return Double(x)
case let x as Int16:
return Double(x)
case let x as UInt16:
return Double(x)
case let x as Int32:
return Double(x)
case let x as UInt32:
return Double(x)
case let x as Int64:
return Double(x)
case let x as UInt64:
return Double(x)
case let x as NSNumber:
return Double(truncating: x)
case let x as String:
return Double(x)
default:
return nil
}
}
///Provides a string representation of your number formatted to include x digits
/// - parameter from: The value you need to convert
/// - parameter digits: The number of digits to include after "."
/// - parameter withOption: Optional: default behavior is to round the last digit (.rounded or nil), choose .truncated to just cut off
func digitString<T>(from: T, digits: Int, withRoundingOption: digitStringOptions?) -> String? {
if let double = genericToDouble(from) {
if withRoundingOption == .truncated {
//Adds an extra digit so rounding affects that one, then cuts it out of the string
return String(String(format: "%.\(digits + 1)f", double).dropLast())
}
return String(format: "%.\(digits)f", double)
} else {
return nil
}
}
///Protocol for class types that can be converted to a formatted number string
protocol DigitString {
func toNumericStringWith(digits: Int, withRoundingOption: digitStringOptions?) -> String?
}
extension DigitString {
///Provides a string representation of your number formatted to include x digits
/// - parameter digits: The number of digits to include after "."
/// - parameter withRoundingOption: Optional: default Swift behavior is to round the last digit (.rounded or nil), choose .truncated to just cut off
func toNumericStringWith(digits: Int, withRoundingOption: digitStringOptions?) -> String? {
return digitString(from: self, digits: digits, withRoundingOption: withRoundingOption)
}
}
//Application of protocol to relevant classes
extension Double: DigitString {}
extension CGFloat: DigitString {}
extension Float: DigitString {}
extension Int: DigitString {}
extension UInt: DigitString {}
extension Int8: DigitString {}
extension UInt8: DigitString {}
extension Int16: DigitString {}
extension UInt16: DigitString {}
extension Int32: DigitString {}
extension UInt32: DigitString {}
extension Int64: DigitString {}
extension UInt64: DigitString {}
extension NSNumber: DigitString {}
extension String: DigitString {}
//extension NSObject: DigitString {} //This would apply it to all Classes(I think?) but I'd rather limit it to ones that will work and are factored into the conversion enum
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment