【问题标题】:for loop creating duplicates. iOS, Swiftfor 循环创建重复项。 iOS、斯威夫特
【发布时间】:2018-01-21 01:24:40
【问题描述】:

我有一个循环,它获取一个数组的元素,该数组是邮政编码,并在 for 循环中将它们更改为纬度、经度、标题和邮政编码,而不是创建并附加一个带有结果的字典数组。原始数组中有 3 个邮政编码,它通过打印显示了这一点,但由于某种原因,循环不仅循环了 3 次,而且循环了很多次,这给了我重复的数据,我已经研究过删除重复项这在某种程度上通过给我留下 3 个结果而起作用,但有时结果还可以,其中邮政编码和标题都不同,但在某些情况下,它会返回相同的标题,但有 2 个不同的邮政编码。

谁能帮我指出正确的方向?

self.places = self.pCodes

// Loop start
for eachAddress in self.places {
                                let geocoder = CLGeocoder()
                                geocoder.geocodeAddressString(eachAddress) {
                                    placemarks, error in
                                    let placemark = placemarks?.first
                                    let lat = placemark?.location?.coordinate.latitude
                                    let lon = placemark?.location?.coordinate.longitude
                                    let postPcode = eachAddress
                                    let locationTitle = self.cNames[self.lt]
                                    let latLon = ["Post Code": postPcode, "title": locationTitle, "latitude":lat!, "longitude": lon!] as [String : Any]

                                    self.posts.append(latLon)

                                 // adding 1 to lt to pick the next title in the array

                                    if self.lt < (self.pCodes.count - 1) {
                                    self.lt += 1

                                    }else {
                                        self.lt = (self.pCodes.count - 1)
                            }


                                // removing duplicates
                                    var set = Set<String>()
                                    let arraySet: [[String : Any]] = self.posts.flatMap {
                                        guard let name = $0["Post Code"] as? String else {return nil }
                                        return set.insert(name).inserted ? $0 : nil
                                    }


                                    self.postsFinal = arraySet
                                    print("Tony Places \(self.places)")
                                    print("Tony: postsFinal \(self.postsFinal)")
                                    self.showSightingsOnMap()
                        }
                    }

这是我得到的打印输出。

托尼·普莱斯 [“OL8 2TT”、“PO1 5DS”、“PO1 5JA”] 托尼:postsFinal [[“纬度”:53.514649900000002,“邮政编码”:“OL8 2TT”,“标题”:“JDFG VBF”,“经度”:-2.1052824000000001]] 托尼·普莱斯 [“OL8 2TT”、“PO1 5DS”、“PO1 5JA”] 托尼:postsFinal [[“纬度”:53.514649900000002,“邮政编码”:“OL8 2TT”,“标题”:“JDFG VBF”,“经度”:-2.1052824000000001]] 托尼·普莱斯 [“OL8 2TT”、“PO1 5DS”、“PO1 5JA”] 托尼:postsFinal [[“纬度”:53.514649900000002,“邮政编码”:“OL8 2TT”,“标题”:“JDFG VBF”,“经度”:-2.1052824000000001]] 托尼·普莱斯 [“OL8 2TT”、“PO1 5DS”、“PO1 5JA”] 托尼:postsFinal [[“纬度”:53.514649900000002,“邮政编码”:“OL8 2TT”,“标题”:“JDFG VBF”,“经度”:-2.1052824000000001],[“纬度”:50.800523599999998,“邮政编码”: “PO1 5DS”、“标题”:“QWER QWE”、“经度”:-1.0723248000000001]] 托尼·普莱斯 [“OL8 2TT”、“PO1 5DS”、“PO1 5JA”] 托尼:postsFinal [[“纬度”:53.514649900000002,“邮政编码”:“OL8 2TT”,“标题”:“JDFG VBF”,“经度”:-2.1052824000000001],[“纬度”:50.800523599999998,“邮政编码”: “PO1 5DS”,“标题”:“QWER QWE”,“经度”:-1.0723248000000001],[“纬度”:50.802415099999997,“邮政编码”:“PO1 5JA”,“标题”:“QWER QWE”,“经度” “:-1.0726989]] 托尼·普莱斯 [“OL8 2TT”、“PO1 5DS”、“PO1 5JA”] 托尼:postsFinal [[“纬度”:53.514649900000002,“邮政编码”:“OL8 2TT”,“标题”:“JDFG VBF”,“经度”:-2.1052824000000001],[“纬度”:50.800523599999998,“邮政编码”: “PO1 5DS”,“标题”:“QWER QWE”,“经度”:-1.0723248000000001],[“纬度”:50.802415099999997,“邮政编码”:“PO1 5JA”,“标题”:“QWER QWE”,“经度” ":-1.0726989]]

【问题讨论】:

  • 你能发布 pCodes 的声明吗?是NSArray、Array等吗
  • @Kris Gellci var pCodes = [String]() pCodes 是与地点完全相同的邮政编码数组。我从 Firebase 数据库中获取邮政编码作为键并将它们放入数组中。我也有 var cNames = [String]() 这是数据库的值,这些也被放入一个数组中。所以我基本上有 2 个数组 1 个键和来自 firebase 的另一个值,然后将它们与其他 2 个元素相加以创建字典。然后我将字典数组附加到帖子中。
  • 您处理异步调用的方式很奇怪。我会使用dispatch_group()而不是:stackoverflow.com/questions/39465789/…
  • 好的,谢谢您的建议,我会考虑调度以使这项工作更好地为我工作。

标签: ios arrays dictionary for-loop


【解决方案1】:

此代码存在一些问题。首先,最大的问题是 geocodeAddressString。这是一个异步调用,您无法保证调用它的顺序。正在处理异步调用内部的索引,这就是您获得不匹配对象的原因。

geocodeAddressString 完成块内的代码不会按照您编码的顺序执行。假设您在 self.places 数组中有 5 个元素。对于每个人,您都会调用 geocodeAddressString。

geocodeAddressString(1)
geocodeAddressString(2)
geocodeAddressString(3)
geocodeAddressString(4)
geocodeAddressString(5)

geocodeAddressString 执行完成块的顺序可能是这样的:

geocodeAddressString(2)
geocodeAddressString(5)
geocodeAddressString(1)
geocodeAddressString(3)
geocodeAddressString(4)

这是因为 geocodeAddressString 正在做一些需要花费大量时间的工作,可能是网络调用。它会在获得正确信息后立即返回,这意味着对它进行 5 次调用将使它们都以不同的速率返回。把它想象成一场有 5 名选手的比赛。

【讨论】:

  • 这很有道理,谢谢你提供的信息,我会再看看这个。
猜你喜欢
  • 2023-03-17
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 2017-07-22
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 2016-11-23
相关资源
最近更新 更多