在字符串数组中搜索多个单词(或字符)(swift)

时间:2017-10-09 20:30:42

标签: arrays swift string

我正在开发一个单词应用程序。 我的问题类似于问题:this

但是,我想在字符串数组中进行搜索。

let myArr: [String] = ["BERLIN","ISTANBUL","TOKYO","NEWYORK","PRAGUE","WIEN"]
    let findChrs = ["I","N"]

   // myArr.contains(findChrs)  //so error

我想:返回 3 或“BERL IN ”,“ STA N BUL”和“W E N ”(包含“我”和“N”)

我试了一下,但是太长了......(我个别看。太多的话。):

for i in 0...myArr.count - 1 {

        let success = !findChrs.contains(where: { !myArr[i].contains($0) })
        if success {
            print(myArr[i])
        }

    }

有更简单的方法吗?非常感谢你。

2 个答案:

答案 0 :(得分:2)

有一种解决问题的方法

我开始使用硬编码搜索词在myArr数组上只使用一个过滤器

let filteredStrings : [String] = myArr.filter({
        return $0.contains("I") && $0.contains("N")
    })

但只有当你的findChars总是只有I和N时才会有所帮助。

后来我意识到如何在不对查找字符字符进行硬编码的情况下执行此操作:

答案1

let myArr: [String] = ["BERLIN","ISTANBUL","TOKYO","NEWYORK","PRAGUE","WIEN"]
let findChrs = ["I","N"]

let filteredStrings : [String] = myArr.filter({ (aString) in

    let hasChars = findChrs.filter({(bString) in
        return aString.contains(bString)
    })

    print(hasChars)

    return hasChars.count == findChrs.count
})

print(filteredStrings)

我认为在第二代代码中,不是使用0美元,而是更容易理解aStringbString发生的事情。

检查游乐场中的代码并查看此代码的工作原理。如果您还没有使用高阶函数,那么理解没有操场和打印语句的过滤器可能会有点令人生畏。

<强>更新

刚考虑这个问题,我尝试使用套装,地图和过滤器尝试这种替代方法。它非常好,很难阅读/理解:

答案2,简洁

let myArr: [String] = ["BERLIN","ISTANBUL","TOKYO","NEWYORK","PRAGUE","WIEN"]
let findChrs = ["I","N"]
let finderSet:Set<String> = Set(findChrs)
let filteredArray = myArr.filter {
    return Set($0.characters.map({String($0)})).intersection(finderSet).count == findChrs.count
}

为了便于阅读和理解,以下是发生的事情:

回答2,详细

let filteredArray = myArr.filter { (aString) -> Bool in

    //for each string in myArr, convert it into an array of string chars
    let stringArray = aString.characters.map({aCharacter in
        String(aCharacter)
    })

    //convert string array into a set
    let aSet = Set(stringArray)

    // find the intersection (common elemnts from aSet and finderSet)
    let intersect = aSet.intersection(finderSet)

    //return true if aString has all of findChrs elements
    return intersect.count == findChrs.count
}

回答2 '简明'和'详细'都会给你相同的结果。

基于一些简单的代码执行时间检查,它看起来像答案1 答案2 快3倍。所以,答案1 仍然是一个更好的选择,可能更容易理解。

希望这有助于任何阅读答案的人了解过滤器和地图!

答案 1 :(得分:1)

如果您没有查找包含重复字母的模式,您也可以使用过滤器集:

let myArr: [String] = ["BERLIN","ISTANBUL","TOKYO","NEWYORK","PRAGUE","WIEN"]
let findChrs = Set<Character>(["I","N"])   // let findChrs = Set("IN")

let matchingCities = myArr.filter{ findChrs.isSubset(of:$0) }