Ios 将由4个数字组成的字符串解析为CGRect
我有这个字符串Ios 将由4个数字组成的字符串解析为CGRect,ios,string,swift,Ios,String,Swift,我有这个字符串(325140739979)。我想对它进行解析,分别取四个数字 此字符串表示一个CGRect。我想取第一个数字为x第二个数字为y第三个数字为width,最后一个数字为height 实现这一点的最佳方法是什么?首先,我们可以去掉括号 let myString = "(325, 140, 739, 979)" let myReplacementString = String(map(myString.generate()) { $0 == "(" || $0 == ")" ? "-
(325140739979)
。我想对它进行解析,分别取四个数字
此字符串表示一个CGRect
。我想取第一个数字为x
第二个数字为y
第三个数字为width
,最后一个数字为height
实现这一点的最佳方法是什么?首先,我们可以去掉括号
let myString = "(325, 140, 739, 979)"
let myReplacementString = String(map(myString.generate()) {
$0 == "(" || $0 == ")" ? "-" : $0
})
您还可以使用子字符串,这似乎没有更好的效果
然后我们可以将字符串拆分为数组
var myArray = myReplacementString.componentsSeparatedByString(", ")
然后使用循环将字符串强制转换为int
for item in myArray {
item.toInt()
}
或者只需使用myArray[i].toInt()将它们直接提供给构造函数等。以下是我针对您的案例的解决方案:
func parse(str : String) -> [Int] {
var firstStepStr = str.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "()")) //remove ( and )
var secondStepArray = firstStepStr.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: ", ")).filter{$0 != ""} //separated by , and ignore ""
return secondStepArray.map{$0.toInt() ?? 0} //convert to [Int], if cannot convert to Int, return 0
}
let cgrectString = "(325, 140, 739, 979)"
let intArray = parse(cgrectString)
这将得到一个包含四个CGFloat值的数组:
func stringToCGFloatArray(string: String) -> [CGFloat] {
return string.componentsSeparatedByCharactersInSet(
NSCharacterSet(charactersInString: "(), ")).reduce([CGFloat]()) {
if let x = $1.toInt() {
return $0 + [CGFloat(x)]
} else {
return $0
}
}
}
然后可以将其转换为可选元组,该元组可以直接提供给CGMakeRect
:
func arrayToRectParameters(array: [CGFloat]) -> (CGFloat, CGFloat, CGFloat, CGFloat)? {
switch array.count {
case 4:
return (array[0], array[1], array[2], array[3])
default:
return nil
}
}
extension CGRect {
init?(string: String) {
// note, since CGRect also has a contains method, need to specify Swift.contains
let nums = split(string) { Swift.contains("(), ", $0) }.map { $0.toInt() }
if nums.count == 4,
let x = nums[0], y = nums[1],
w = nums[2], h = nums[3]
{
self = CGRect(x: x, y: y, width: w, height: h)
}
else {
return nil
}
}
}
let rectangles = [
"(325, -140, 739, 979)", // valid
"(1,2,3,asdadaf)", // invalid (non-integer)
"1,2,3,4,", // valid
"(1,2,3,4,5)", // invalid (wrong count)
]
// returns an array of 2 valid CGRect and 2 nil
let cgrects = rectangles.map { CGRect(string: $0) }
现在您可以创建一个CGRect,如下所示:
let str = "(325, 140, 739, 979)"
if let rectParameters = arrayToRectParameters(stringToCGFloatArray(str)) {
let myCGRect = CGRectMake(rectParameters)
println(myCGRect) // prints (325.0,140.0,739.0,979.0)
}
let str = "(325, 140, 739, 979)"
let nums = split(str) { contains("(), ", $0) }.map { $0.toInt() }
给定字符串,可以将数字作为可选的
Int
数组获取,如下所示:
let str = "(325, 140, 739, 979)"
if let rectParameters = arrayToRectParameters(stringToCGFloatArray(str)) {
let myCGRect = CGRectMake(rectParameters)
println(myCGRect) // prints (325.0,140.0,739.0,979.0)
}
let str = "(325, 140, 739, 979)"
let nums = split(str) { contains("(), ", $0) }.map { $0.toInt() }
split
将删除传递给contains
的字符串中的任何字符。现在,您有了一个选项数组,可以检查其内容是否正确:
let rect: CGRect
if nums.count == 4,
let x = nums[0], y = nums[1],
w = nums[2], h = nums[3]
{
rect = CGRect(x: x, y: y, width: w, height: h)
}
else {
// report an error, or default the values if you prefer
fatalError("Malformed input string")
}
输入字符串中的任何无关字符都将导致其中一个整数的nil
,或者数组中的计数错误,因此这对于任何垃圾输入都是安全的
为了方便起见,您可以将所有这些都放在CGRect
的可失败初始值设定项中:
func arrayToRectParameters(array: [CGFloat]) -> (CGFloat, CGFloat, CGFloat, CGFloat)? {
switch array.count {
case 4:
return (array[0], array[1], array[2], array[3])
default:
return nil
}
}
extension CGRect {
init?(string: String) {
// note, since CGRect also has a contains method, need to specify Swift.contains
let nums = split(string) { Swift.contains("(), ", $0) }.map { $0.toInt() }
if nums.count == 4,
let x = nums[0], y = nums[1],
w = nums[2], h = nums[3]
{
self = CGRect(x: x, y: y, width: w, height: h)
}
else {
return nil
}
}
}
let rectangles = [
"(325, -140, 739, 979)", // valid
"(1,2,3,asdadaf)", // invalid (non-integer)
"1,2,3,4,", // valid
"(1,2,3,4,5)", // invalid (wrong count)
]
// returns an array of 2 valid CGRect and 2 nil
let cgrects = rectangles.map { CGRect(string: $0) }
很明显,如果你想在你愿意转换的输入类型上或多或少的宽容,这里有很多可以调整的地方