如何创建一个字符串的格式?

我需要创建一个具有格式的String,可以将IntInt64Double等类型转换为String。使用Objective-C,我可以通过:

NSString *str = [NSString stringWithFormat:@"%d , %f, %ld, %@", INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, STRING_VALUE];

如何做同样的,但在Swift?

323489 次浏览

没有什么特别的

let str = NSString(format:"%d , %f, %ld, %@", INT_VALUE, FLOAT_VALUE, LONG_VALUE, STRING_VALUE)
let str = "\(INT_VALUE), \(FLOAT_VALUE), \(DOUBLE_VALUE), \(STRING_VALUE)"

我在Swift将String(format:)添加到它的API之前写了这个答案。使用上面的回答给出的方法。

使用下面的代码:

    let intVal=56
let floatval:Double=56.897898
let doubleValue=89.0
let explicitDaouble:Double=89.56
let stringValue:"Hello"


let stringValue="String:\(stringValue) Integer:\(intVal) Float:\(floatval) Double:\(doubleValue) ExplicitDouble:\(explicitDaouble) "

首先读Swift语言的官方文档。

答案应该是

var str = "\(INT_VALUE) , \(FLOAT_VALUE) , \(DOUBLE_VALUE), \(STRING_VALUE)"
println(str)

在这里

1)任何浮点值,默认为double

EX.
var myVal = 5.2 // its double by default;

->如果你想显示浮点值,那么你需要显式地定义像a

 EX.
var myVal:Float = 5.2 // now its float value;

这要清楚得多。

let INT_VALUE=80
let FLOAT_VALUE:Double= 80.9999
let doubleValue=65.0
let DOUBLE_VALUE:Double= 65.56
let STRING_VALUE="Hello"


let str = NSString(format:"%d , %f, %ld, %@", INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, STRING_VALUE);
println(str);

我认为这可以帮助你:

import Foundation


let timeNow = time(nil)
let aStr = String(format: "%@%x", "timeNow in hex: ", timeNow)
print(aStr)

结果示例:

timeNow in hex: 5cdc9c8d

成功尝试一下:

 var letters:NSString = "abcdefghijkl"
var strRendom = NSMutableString.stringWithCapacity(strlength)
for var i=0; i<strlength; i++ {
let rndString = Int(arc4random() % 12)
//let strlk = NSString(format: <#NSString#>, <#CVarArg[]#>)
let strlk = NSString(format: "%c", letters.characterAtIndex(rndString))
strRendom.appendString(String(strlk))
}

不需要NSString !

String(format: "Value: %3.2f\tResult: %3.2f", arguments: [2.7, 99.8])

String(format:"Value: %3.2f\tResult: %3.2f", 2.7, 99.8)

我认为两者都有

let str = String(format:"%d, %f, %ld", INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE)

而且

let str = "\(INT_VALUE), \(FLOAT_VALUE), \(DOUBLE_VALUE)"

都是可接受的,因为用户询问格式,这两种情况都符合他们的要求:

我需要创建一个字符串的格式,可以转换int, long, double等类型的字符串。

显然,前者可以比后者更好地控制格式,但这并不意味着后者不是一个可接受的答案。

我知道自从这篇文章发表以来已经过去了很多时间,但我也遇到过类似的情况,所以创建了一个simples类来简化我的生活。

public struct StringMaskFormatter {


public var pattern              : String    = ""
public var replecementChar      : Character = "*"
public var allowNumbers         : Bool      = true
public var allowText            : Bool      = false




public init(pattern:String, replecementChar:Character="*", allowNumbers:Bool=true, allowText:Bool=true)
{
self.pattern            = pattern
self.replecementChar    = replecementChar
self.allowNumbers       = allowNumbers
self.allowText          = allowText
}




private func prepareString(string:String) -> String {


var charSet : NSCharacterSet!


if allowText && allowNumbers {
charSet = NSCharacterSet.alphanumericCharacterSet().invertedSet
}
else if allowText {
charSet = NSCharacterSet.letterCharacterSet().invertedSet
}
else if allowNumbers {
charSet = NSCharacterSet.decimalDigitCharacterSet().invertedSet
}


let result = string.componentsSeparatedByCharactersInSet(charSet)
return result.joinWithSeparator("")
}


public func createFormattedStringFrom(text:String) -> String
{
var resultString = ""
if text.characters.count > 0 && pattern.characters.count > 0
{


var finalText   = ""
var stop        = false
let tempString  = prepareString(text)


var formatIndex = pattern.startIndex
var tempIndex   = tempString.startIndex


while !stop
{
let formattingPatternRange = formatIndex ..< formatIndex.advancedBy(1)


if pattern.substringWithRange(formattingPatternRange) != String(replecementChar) {
finalText = finalText.stringByAppendingString(pattern.substringWithRange(formattingPatternRange))
}
else if tempString.characters.count > 0 {
let pureStringRange = tempIndex ..< tempIndex.advancedBy(1)
finalText = finalText.stringByAppendingString(tempString.substringWithRange(pureStringRange))
tempIndex = tempIndex.advancedBy(1)
}


formatIndex = formatIndex.advancedBy(1)


if formatIndex >= pattern.endIndex || tempIndex >= tempString.endIndex {
stop = true
}


resultString = finalText


}
}


return resultString
}


}
下面的链接发送到完整的源代码: https://gist.github.com/dedeexe/d9a43894081317e7c418b96d1d081b25 < / p > 这个解决方案是基于这篇文章: http://vojtastavik.com/2015/03/29/real-time-formatting-in-uitextfield-swift-basics/ < / p >

我从“We <3 Swift”中学到了一个简单的解决方案,如果你不能进口的基础,使用圆的()和/或不想要字符串:

var number = 31.726354765
var intNumber = Int(number * 1000.0)
var roundedNumber = Double(intNumber) / 1000.0

结果:31.726

String(format:)的美妙之处在于,你可以保存一个格式化字符串,然后在很多地方重复使用。它也可以本地化到这个地方。在插值的情况下,你必须一遍又一遍地写。

简单的功能没有包含在Swift中,这是意料之中的,因为它包含在其他语言中,通常可以快速编码以便重用。为程序员创建一个包含所有这些重用代码的技巧包文件的专业提示。

从我的技巧包中,我们首先需要在缩进中使用字符串乘法。

@inlinable func * (string: String, scalar: Int) -> String {
let array = [String](repeating: string, count: scalar)
return array.joined(separator: "")
}

然后是添加逗号的代码。

extension Int {
@inlinable var withCommas:String {
var i = self
var retValue:[String] = []
while i >= 1000 {
retValue.append(String(format:"%03d",i%1000))
i /= 1000
}
retValue.append("\(i)")
return retValue.reversed().joined(separator: ",")
}


@inlinable func withCommas(_ count:Int = 0) -> String {
let retValue = self.withCommas
let indentation = count - retValue.count
let indent:String = indentation >= 0 ? " " * indentation : ""


return indent + retValue
}
}

我只是写了最后一个函数这样我就可以让列对齐。

@inlinable很棒,因为它采用小函数并减少它们的功能,从而运行得更快。

您可以使用变量版本,也可以使用函数版本来获得固定的列。长度设置小于所需列只会扩展字段。

现在你有一些纯粹的Swift,不依赖于一些旧的objective C例程的NSString。

公认的答案肯定是最好的通用解决方案(即,只需使用Foundation中的String(format:_:)方法),但是…

如果你运行的是Swift≥5,你可以利用新的StringInterpolationProtocol协议为你的应用程序中常见的字符串格式化用例提供一些非常好的语法糖

以下是官方文件对这项新协议的总结:

表示在构建字符串文字时进行插值的字符串文字的内容。

一些简单的例子:

extension String.StringInterpolation {


/// Quick formatting for *floating point* values.
mutating func appendInterpolation(float: Double, decimals: UInt = 2) {
let floatDescription = String(format: "%.\(decimals)f%", float)
appendLiteral(floatDescription)
}


/// Quick formatting for *hexadecimal* values.
mutating func appendInterpolation(hex: Int) {
let hexDescription = String(format: "0x%X", hex)
appendLiteral(hexDescription)
}


/// Quick formatting for *percents*.
mutating func appendInterpolation(percent: Double, decimals: UInt = 2) {
let percentDescription = String(format: "%.\(decimals)f%%", percent * 100)
appendLiteral(percentDescription)
}


/// Formats the *elapsed time* since the specified start time.
mutating func appendInterpolation(timeSince startTime: TimeInterval, decimals: UInt = 2) {
let elapsedTime = CACurrentMediaTime() - startTime
let elapsedTimeDescription = String(format: "%.\(decimals)fs", elapsedTime)
appendLiteral(elapsedTimeDescription)
}
}

可用作:

let number = 1.2345
"Float: \(float: number)" // "Float: 1.23"
"Float: \(float: number, decimals: 1)" // "Float: 1.2"


let integer = 255
"Hex: \(hex: integer)" // "Hex: 0xFF"


let rate = 0.15
"Percent: \(percent: rate)" // "Percent: 15.00%"
"Percent: \(percent: rate, decimals: 0)" // "Percent: 15%"


let startTime = CACurrentMediaTime()
Thread.sleep(forTimeInterval: 2.8)
"∆t was \(timeSince: startTime)" // "∆t was 2.80s"
"∆t was \(timeSince: startTime, decimals: 0)" // "∆t was 3s"

这是由se - 0228引入的,所以请一定要阅读原始提案,以更深入地了解这个新功能。最后,协议文档也是有用的。

由于String(format: "%s" ...)在运行时崩溃,下面是允许编写类似"hello".center(42); "world".alignLeft(42)的代码:

extension String {


// note: symbol names match to nim std/strutils lib:


func align (_ boxsz: UInt) -> String {
self.withCString { String(format: "%\(boxsz)s", $0) }
}


func alignLeft (_ boxsz: UInt) -> String {
self.withCString { String(format: "%-\(boxsz)s", $0) }
}


func center (_ boxsz: UInt) -> String {
let n = self.count
guard boxsz > n else { return self }
let padding = boxsz - UInt(n)
let R = padding / 2
guard R > 0 else { return " " + self }
let L = (padding%2 == 0) ? R : (R+1)
return " ".withCString { String(format: "%\(L)s\(self)%\(R)s", $0,$0) }
}


}