How to insert character into string in Swift 2.0? - swift2

This function takes in an Int like 324543 and returns a String like "$3245.43"
My attempt is below, but Swift 2 does not like atIndex: 0
How would I go about inserting characters into a string instead?
func stylizeCents (cent: Int) -> String {
var styledCents = String(cent)
let dollarSign : Character = "$"
let dot : Character = "."
let count = styledCents.characters.count
styledCents.insert(dollarSign, atIndex: 0) // error
styledCents.insert(dot, atIndex: count-1) // error
}

This appears to have already been solved in this answer.
Swift 2.0
You can use a string extension:
extension String {
func insert(string:String,ind:Int) -> String {
return String(self.characters.prefix(ind)) + string + String(self.characters.suffix(self.characters.count-ind))
}
}
used like:
var url = "http://www.website.com"
url = url.insert("s", ind: 4) // outputs https://www.website.com

Related

Generic parameter 'Self' could not be inferred (swift 4)

I want to make a substring extension for string , I tried below 2 ways but unsuccessful:
extension String
{
func substringToFirstChar(of char: Character) -> String
{
let pos = self.range(of: String(char))
let subString = self[..<pos?.lowerBound]
return String(subString)
}
}
or
extension String
{
func substringToFirstChar(of char: Character) -> String
{
let pos = self.index(of: char)
let subString = self[..<pos]
return String(subString)
}
}
xcode prompt error: Generic parameter 'Self' could not be inferred at the "let subString = self[.." line.
How to do that ?
range(of / index(of returns an optional. You have to unwrap the optional in the range expression
extension String
{
func substringToFirstChar(of char: Character) -> String?
{
guard let pos = self.range(of: String(char))?.lowerBound else { return nil }
// or guard let pos = self.index(of: char) else { return nil }
let subString = self[..<pos]
return String(subString)
}
}
alternatively – to avoid the optional – return the unchanged string if there is no match
extension String
{
func substringToFirstChar(of char: Character) -> String
{
guard let pos = self.range(of: String(char))?.lowerBound else { return self }
// or guard let pos = self.index(of: char) else { return self }
let subString = self[..<pos]
return String(subString)
}
}

How to use thousand separator swift

func showNumbers(){
if let inputString = numberInput.text {
let input = Int(inputString)
let nums = input?.formattedWithSeparator
let group = Int(round(groupslider.value))
let priceEach = Int(round(Double((nums)!/group*100))/100)
perperson.text = String(priceEach)
}
}
}
extension Formatter {
static let withSeparator: NumberFormatter = {
let formatter = NumberFormatter()
formatter.groupingSeparator = " "
formatter.numberStyle = .decimal
return formatter
}()
}
extension BinaryInteger {
var formattedWithSeparator: String {
return Formatter.withSeparator.string(for: self) ?? ""
}
}
I have two places that I want to make it like 1,000,000
input String and perperson.text
what should I use? NSNumberForatter?
I want to use thousandSeparator or groupSeparator.
I get " Binary operator '/' cannot be applied to operands of type 'String' and 'Int' " this error message.

Generating HMAC-SHA256 from Byte-Array in Swift

I want to create a signature for the myJD REST-API. But the first snippet is not working. I talked to the support and they told me that I need the unhexed key to create the correct hash. So I created a Byte-Array of the Hex-Value and changed the code to work again (see second snippet). Both methods have the same result.
Link to API documentation: https://docs.google.com/document/d/1IGeAwg8bQyaCTeTl_WyjLyBPh4NBOayO0_MAmvP5Mu4/edit?pref=2&pli=1
First:
import Foundation
extension String{
func hmacSHA256(key: String) -> String {
let str = self.cStringUsingEncoding(NSUTF8StringEncoding)
let strLen = Int(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
let digestLen = Int(CC_SHA256_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
let keyStr = key.cStringUsingEncoding(NSUTF8StringEncoding)!
let keyLen = Int(key.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyStr, keyLen, str!, strLen, result)
let digest = stringFromResult(result, length: digestLen)
result.dealloc(digestLen)
return digest
}
private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
let hash = NSMutableString()
for i in 0..<length {
hash.appendFormat("%02x", result[i])
}
return String(hash)
}
}
Second:
func hmacSHA256_2(key: String) -> String {
//let cKey = key.dataUsingEncoding(NSUTF8StringEncoding)!
let bKey = Array(key.utf8)
let bData = Array(self.utf8)
//let cData = self.dataUsingEncoding(NSUTF8StringEncoding)!
var cHMAC = [CUnsignedChar](count: Int(CC_SHA256_DIGEST_LENGTH), repeatedValue: 0)
CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), bKey, Int(bKey.count), bData, Int(bData.count), &cHMAC)
let output = NSMutableString(capacity: Int(CC_SHA256_DIGEST_LENGTH))
for byte in cHMAC {
output.appendFormat("%02hhx", byte)
}
return output as String
}

How to remove multiple spaces in Strings with Swift 2

Until Swift 2 I used this extension to remove multiple whitespaces:
func condenseWhitespace() -> String {
let components = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).filter({!Swift.isEmpty($0)})
return " ".join(components)
}
but with Swift 2 now I get the error
Cannot invoke 'isEmpty' with an argument list of type '(String)'
How could I now remove multiple spaces with Swift 2?
Thnx!
In Swift 2, join has become joinWithSeparator and you call it on the array.
In filter, isEmpty should be called on the current iteration item $0.
To replace whitespaces and newline characters with unique space characters as in your question:
extension String {
func condenseWhitespace() -> String {
let components = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
return components.filter { !$0.isEmpty }.joinWithSeparator(" ")
}
}
let result = "Hello World.\nHello!".condenseWhitespace() // "Hello World. Hello!"
Because your function does not take any parameter you could make it a property instead:
extension String {
var condensedWhitespace: String {
let components = self.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
return components.filter { !$0.isEmpty }.joinWithSeparator(" ")
}
}
let result = "Hello World.\nHello!".condensedWhitespace // "Hello World. Hello!"
In Swift 3 there's even more changes.
Function:
extension String {
func condenseWhitespace() -> String {
let components = self.components(separatedBy: NSCharacterSet.whitespacesAndNewlines)
return components.filter { !$0.isEmpty }.joined(separator: " ")
}
}
let result = "Hello World.\nHello!".condenseWhitespace()
Property:
extension String {
var condensedWhitespace: String {
let components = self.components(separatedBy: NSCharacterSet.whitespacesAndNewlines)
return components.filter { !$0.isEmpty }.joined(separator: " ")
}
}
let result = "Hello World.\nHello!".condensedWhitespace
In Swift 4.2 NSCharacterSet is now CharacterSet, and you can omit and use dot syntax:
extension String {
func condenseWhitespace() -> String {
let components = self.components(separatedBy: .whitespacesAndNewlines)
return components.filter { !$0.isEmpty }.joined(separator: " ")
}
}
let result = "Hello World.\nHello!".condenseWhitespace() // "Hello World. Hello!"
Split string to array and then join again in not memory efficient. Its Takes lot of memory. The best way in this case is to scan the given string and perform operations on that. Regular Expression is the advance way to scan a text. For the above conclusion the the solution is given below:
Swift 4.x
extension String {
func removeExtraSpaces() -> String {
return self.replacingOccurrences(of: "[\\s\n]+", with: " ", options: .regularExpression, range: nil)
}
}
Usages
let startingString = "hello world! \n\n I am here!"
let processedString = startingString.removeExtraSpaces()
print(processedString)
Output:
processedString => "hello world! I am here!"
You can Do more according to your own requirements but thing I am pointing out here is to use regular expressions with string rather then create arrays which will consume lot of memory.
Cleanest version. Documented, memory efficient, extremely easy to use.
extension String {
/// Returns a condensed string, with no extra whitespaces and no new lines.
var condensed: String {
return replacingOccurrences(of: "[\\s\n]+", with: " ", options: .regularExpression, range: nil)
}
/// Returns a condensed string, with no whitespaces at all and no new lines.
var extraCondensed: String {
return replacingOccurrences(of: "[\\s\n]+", with: "", options: .regularExpression, range: nil)
}
}
Usage:
let a = " Hello\n I am a string ".condensed
let b = " Hello\n I am a string ".extraCondensed
Output:
a: "Hello I am a string"
b: "HelloIamastring"
SWIFT 3: Cleaner version
extension String {
var condensedWhitespace: String {
let components = self.components(separatedBy: .whitespacesAndNewlines)
return components.filter { !$0.isEmpty }.joined(separator: " ")
}
}
Here is mine: How it's actually worked.
extension String {
func removeExtraSpaces() -> String {
var data = ""
var numberOfSpace = 0
let items = self.getComponents(separatedBy: " ")
for item in items{
if item == " "{
numberOfSpace = numberOfSpace + 1
}else{
numberOfSpace = 0
}
if numberOfSpace == 1 || numberOfSpace == 0 {
data = data + item
//data.append(item)
}
}
return data
}
}
Usages
var message = "What is the purpose of life?"
message = message.removeExtraSpaces()
print(message)
Output:
What is the purpose of life?
var str = "Hello World.\nHello!"
if let regex = try? NSRegularExpression(pattern: "\\s+", options:NSRegularExpression.Options.caseInsensitive)
{
str = regex.stringByReplacingMatches(in: str, options: [], range: NSMakeRange(0, str.count), withTemplate: " ")
}

Swift: How do I cast a Character as a String to do a simple compare?

I am getting the error at the "==" in code
Cannot invoke '==' with an argument list of type '(#lvalue String, #lvalue Character)'
--------representation of my code
var randomWord = "horse"
var guessLetter = "g"
for var charIndex = 0; charIndex < countElements(randomWord); charIndex++ {
var index = advance(str.startIndex, charIndex)
var oneLetter = str[index]
if guessLetter == oneLetter {
println("ok")
} else {
println("nope")
}
}
One very simple way is to use string interpolation:
if guessLetter == "\(oneLetter)"
Another is to have guessLetter be a Character:
var guessLetter: Character = "g"

Resources