简体   繁体   English

在Swift中当每对元素都是String时,如何迭代一个数组得到2个变量? 和一个字符串

[英]In Swift How do I iterate over an array getting 2 variables when each pair of elements is a String? and a String

I want to iterate over an array String?, String repeated pair but I cannot form the "for case let (a,b) in array" correctly. 我想迭代一个数组String?,String重复对但我不能正确地形成“for case let(a,b)in array”。

The best I have come up with is to create a temp struct of {String?, String} and create an array of the temp structs and then iterate it but I would like to skip this step. 我想出的最好的方法是创建一个{String?,String}的临时结构并创建一个临时结构数组,然后迭代它,但我想跳过这一步。

Below is the basic example with the last for loop showing the error Xcode reports. 下面是最后一个for循环的基本示例,显示了Xcode报告的错误。

class Foo {
    var s1: String?
    var s2: String?
    var s3: String?
}

let foo = Foo()
foo.s1="Test1"
foo.s2=nil
foo.s3="Test3"

let fooArray = [foo.s1, ", ", foo.s2, "; ", foo.s3,"."]
let fooArray1 = [foo.s1,foo.s2, foo.s3]
var text:String = ""
for case let prop? in fooArray1 {
    text = text + prop + " / "
}
print(text)
// The above works but now I want to use a different separator 
//base on the property name

text=""

for case let (prop, sep) in fooArray { // Error <= Expression Type 
// [String?] is ambiguous without more context

    text = text + prop + sep
}
print(text)

Here is what I have come up with 这就是我想出的

struct temp {
    var prop:String?
    var sep:String
    init(_ prop:String?, _ sep:String) {
        self.prop=prop
        self.sep=sep
}

let ary:[temp] = [ temp(foo.s1,", "), temp(foo.s2,"; "), temp(foo.s3,".") ]
text = ""
for a in ary {
    if let p = a.prop {
        text = text + p + a.sep
    }
}
print (text)

is there another way just using the for loop 有没有另一种方法只使用for循环

for (a,b) in fooArray {
...
}

As noted by @RJE, the inferred type of fooArray , as defined in your code, is [String?] . 正如@RJE所指出的,你的代码中定义的推断类型fooArray[String?]

Here is one way to make it work: 这是使其工作的一种方法:

class Foo {
    var s1: String?
    var s2: String?
    var s3: String?
}

let foo = Foo()
foo.s1 = "Test1"
foo.s2 = nil
foo.s3 = "Test3"

let fooArray1  = [foo.s1, foo.s2, foo.s3]
let separators = [", ", "; ", "."]

var text = ""

for i in fooArray1.indices {
    if let p = fooArray1[i] {
        text = text + p + separators[i]
    }
}

print (text)  //Test1, Test3.

Or 要么

let zipped = zip(fooArray1, separators)

let text = zipped.map { tuple -> String in
    if case let (x?, y) = tuple {
        return x + y
    } else {
        return ""
    }
}.joined()

print (text)  //Test1,Test3.

Or 要么

let fooArray = [foo.s1, ", ", foo.s2, "; ", foo.s3, "."]
var text = ""
var step = 1
var index = 0

while index < fooArray.count {
    if let str = fooArray[index] {
        step = 1
        text += str
    } else {
        step = 2
    }
    index += step
}

print(text) //Test1, Test3.

It would be better to define the initializer this way : 以这种方式定义初始化器会更好:

class Foo {
    var s1: String?
    var s2: String?
    var s3: String?

    init(s1: String?, s2: String?, s3: String?) {
        self.s1 = s1
        self.s2 = s2
        self.s3 = s3
    }
}

let foo = Foo(s1: "Test1", s2: nil, s3: "Test3")

PS: The desired output seems to be more appropriate for a description property of the Foo class. PS:所需的输出似乎更适合Foo类的description属性。

Thanks for the answer I was hoping through this question to get a better understanding of how to use [for] parameters. 感谢您希望通过这个问题得到的答案,以便更好地理解如何使用[for]参数。 But the while solution is the solution I would probably use with the following modifications 但是,while解决方案是我可能会使用以下修改的解决方案

text = ""
var index = 0 
while index < fooArray.count {    
    if let prop = fooArray[index] {
        index += 1
        let sep = fooArray[index]!
        index += 1
        text = text + prop + sep
    } else {
        index += 2
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM