确定数组是否包含swift中另一个数组的一个或多个元素

时间:2017-10-10 14:46:01

标签: ios arrays swift google-places-api contains

我有以下代码返回用户当前位置附近的地方

import UIKit
import GooglePlaces
import CoreLocation

struct GlobalVariables {
    static var acceptedEstablishments = ["bakery", "bar", "cafe", "food", "meal_takeaway", "meal_delivery", "night_club", "restaurant", "school", "university"]
}

class ViewController: UIViewController, CLLocationManagerDelegate {

    var placesClient: GMSPlacesClient!
    var locationManager: CLLocationManager!

    // Add a pair of UILabels in Interface Builder, and connect the outlets to these variables.
    @IBOutlet var nameLabel: UILabel!
    @IBOutlet var addressLabel: UILabel!


    override func viewDidLoad() {
        super.viewDidLoad()
        placesClient = GMSPlacesClient.shared()

        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
    }

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        if status == .authorizedWhenInUse {
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.startUpdatingLocation()
        }
    }

    // Add a UIButton in Interface Builder, and connect the action to this function.
    @IBAction func getCurrentPlace(_ sender: UIButton) {

        placesClient.currentPlace(callback: { (placeLikelihoodList, error) -> Void in
            if let error = error {
                print("Pick Place error: \(error.localizedDescription)")
                return
            }

            if let placeLikelihoodList = placeLikelihoodList {
                for likelihood in placeLikelihoodList.likelihoods {
                    let place = likelihood.place
                    // only return places that are relevant to me
                    for placeType in place.types {
                        if (GlobalVariables.acceptedEstablishments.contains(placeType)) {
                            print("Current place name: \(place.name)")
                            print("Place type: \(placeType)")
                        }
                    }

                }
            }
        })
    }
}
底部回调函数中的

place.types返回每个场所实例的字符串数组,如下所示:

["health", "point_of_interest", "establishment"]

我有一个全局字符串数组,其中还包含bakerybar等标记。

当用户按下按钮时,触发回调功能并根据附近位置返回位置。

输出看起来像这样:

Current place name: LOCAL SUPERMARKET
Place type: food
Current place name: LOCAL GRILL
Place type: cafe
Current place name: LOCAL GRILL
Place type: food
Current place name: LOCAL SCHOOL
Place type: school
Current place name: LOCAL TAKEAWAY
Place type: meal_takeaway
Current place name: LOCAL TAKEAWAY
Place type: restaurant
Current place name: LOCAL TAKEAWAY
Place type: food

同一个机构重复多次,因为一个机构有多个与之关联的机柜。

例如:

place.types的{​​{1}}返回的数组是:LOCAL TAKEAWAY

因为我的["meal_takeaway", "restaurant", "food"]数组包含所有这三个字符串,GlobalVariables.acceptedEstablishments命令将被执行三次。

如果print数组包含一个或多个匹配的字符串,那么如何修改此代码以便它只显示一次建立?我似乎无法理解解决方案。

3 个答案:

答案 0 :(得分:3)

你也可以使用套装:

if !Set(place.types).intersection(GlobalVariables.acceptedEstablishments).isEmpty
{
  // there is at least one common element
}

如果你能负担得起GlobalVariables.acceptedEstablishments一个Set,那么这个条件会更有效率,可以写成:

if !GlobalVariables.acceptedEstablishments.intersection(places.types).isEmpty
{
  // there is at least one common element
}

在任何一种情况下,places.types本身都不需要是一个集合。

答案 1 :(得分:2)

Swift Array类允许重复项。 Set类没有。您可以在Array上创建一个扩展,该扩展具有方法uniqueItems,可以删除重复项。请注意,数组中的项必须是Hashable才能使其正常工作。

以下是扩展名。 (不是我的代码 - 取自another SO post

def browseFile(self):
    filename, _ = QFileDialog.getOpenFileName(self, 'Open file', 'c:\\',"xml/html (*.xml *.html)")
    if filename != "":
        self.LRPathComboBox.addItem(filename, 0)

答案 2 :(得分:2)

关键是使用Set,它不会有重复项。 Set是一个集合类,可以类似于数组使用。您可以对其进行迭代,它包含countmapfiltercontains等。

let acceptedPlaces: Set = ["home", "pub", "hospital"]
let availablePlaces: Set = ["home", "pub", "mountains"]
let inBoth = acceptedPlaces.intersection(availablePlaces) // ["home", "pub"]

您可以轻松地从Set s Array创建let someSet = Set(someArray),反之亦然let someArray = Array(someSet)。您可能还想查看Set的以下功能:unionsubstractisSuperSetisSubset