我有一个简单的问题,同时也很难。我有两个独立的结构(这也适用于类):

struct FBTweet {
    var tweetId: Int? //set
    var tweetText: String?  //set
}


struct Status {
    var statusId: Int? //set
    var statusText: String? //no value
    }

我有一个由var fbTweetArray: [FBTweet] = []var statusArray: [Status] = []两个结构组成的数组
我已经将中的每个变量设置为fbTweetArray中每个索引中的特定值,但只为statusArray设置了每个索引中的.statusId变量。对于statusArray中的每个statusArray.statusId值,只有一个fbTweetArray.tweetId具有相同的精确Int值。我想做的是,如果这两个变量相同,我应该设置
statusArray.statusTextfbTweetarray.tweetText是什么。例如,只有fbTweetArray[1].tweetid = 2346statusArray[4].statusId = 2346的值是2346。如果fbTweetArray[1].tweetText = "hello friend"则需要将statusArray[4].statusText设置为“hello friend”。
到目前为止
func testWhat () {

    var fbTweetArray: [FBTweet] = []
    var statusArray: [Status] = []

    for  fbTweet in fbTweetArray {
        for var status in statusArray {
            if (status.statusId == fbTweet.tweetId ) {
                status.statusText = fbTweet.tweetText
            }
        }
    }
}

如何将for循环中的for var status设置回statusArray,因为它现在是一个var,并且不同于var statusArray: [Status] = []中的一个索引

最佳答案

基本上,您只需要一个for/forEach循环就可以实现您想要的:

var fbTweetArray: [FBTweet] = [
    FBTweet(tweetId: 1, tweetText: "1"),
    FBTweet(tweetId: 2, tweetText: "2"),
    FBTweet(tweetId: 3, tweetText: "3")
]

var statusArray: [Status] = [
    Status(statusId: 2, statusText: nil),
    Status(statusId: 1, statusText: nil),
    Status(statusId: 3, statusText: nil)
]

fbTweetArray.forEach { tweet in
    if let index = statusArray.index(where: { $0.statusId == tweet.tweetId }) {
        statusArray[index].statusText = tweet.tweetText
    }
}

print(statusArray.map { $0.statusText }) // [Optional("2"), Optional("1"), Optional("3")]

注意,两个结构中的ids都可以是nil。要处理这种情况(如果两个id都为nil-对象不相等),可以编写custom==func:
struct Status {
    var statusId: Int? //set
    var statusText: String? //no value

    static func == (lhs: Status, rhs: FBTweet) -> Bool {
        guard let lhsId = lhs.statusId, let rhsId = rhs.tweetId else { return false }
        return lhsId == rhsId
    }
}

...

// rewrite .index(where: ) in if condition
if let index = statusArray.index(where: { $0 == tweet }) { ... }

还有一些专业的建议。如果您采用structs toHashable协议,您将能够将FBTweets和Statuses放入Set结构中。这样做的好处是:
如果将这些对象存储在一个集合中,理论上可以
在恒定时间(O(1))中查找其中任何一个-即查找
设置为10个元素所需的时间与查找
设置为10000。
你可以在一个新的伟大的article by NSHipster中找到关于它的更深入的信息。

10-06 09:44