简体   繁体   English

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

[英]Search Multiple Words (or Characters) in String Array (swift)

I am developing an application for words. 我正在开发一个单词的应用程序。 My problem resembles the problem: this 我的问题类似于问题: 这个

But, I want to do the search in the string array. 但是,我想在字符串数组中进行搜索。

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

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

I want to: return 3 or "BERL IN "," I STA N BUL" and "W I E N " (Contains "I" and "N") 我想:返回3或“BERL IN ”,“ I STA N BUL”和“W I E N ”(包含“I”和“N”)

I tried it, but it's too long...(I look individually. Too many words.): 我试了一下,但是太长了......(我个人看。太多的话。):

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

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

    }

Is there an easier way? 有更容易的方法吗? Thank you so much. 非常感谢。

There's a swifty way to solve your problem 有一种解决问题的方法

I started with using just one filter on the myArr array using hardcoded search terms 我开始使用硬编码搜索术语在myArr数组上只使用一个过滤器

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

but thats going to help only if your findChars are always going to be I and N only. 但只有当你的findChars总是只有I和N时才有用。

Later I realized how to do it without hardcoding the find char characters: 后来我意识到如何在不对find char字符进行硬编码的情况下执行此操作:

ANSWER 1 答案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)

Instead of using $0, I think in the second chunk of code, its easier to understand whats happening with aString and bString . 我认为在第二块代码中,它更容易理解使用aStringbString发生的事情,而不是使用0美元。

Do check the code in a playground and see how this code works. 请检查游乐场中的代码并查看此代码的工作原理。 If you haven't used the higher order functions, it can be a little daunting to understand filters without a playground and the print statements. 如果您还没有使用高阶函数,那么理解没有操场和print语句的过滤器可能会有点令人生畏。

Update: 更新:

Was just thinking about this problem and I gave this alternate approach a try, using sets, map and filter. 只是考虑这个问题,我尝试使用集合,地图和过滤器尝试这种替代方法。 It is super swifty, and can be difficult to read/understand: 它非常好,很难阅读/理解:

ANSWER 2, concise 答案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
}

For the sake of readability and ease of understanding, here's what is happening: 为了便于阅读和理解,这里发生了什么:

Answer 2, verbose 答案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
}

Both Answer 2 'concise' and 'verbose' will give you the same results. 答案2 '简洁'和'详细'都会给你相同的结果。

Based on some simple code execution time check, it looks like Answer 1 is ~3x faster than Answer 2 . 基于一些简单的代码执行时间检查,看起来答案1答案2快3倍。 So, Answer 1 is still a better choice and probably easier to understand. 所以, 答案1仍然是一个更好的选择,可能更容易理解。

Hope this helps anyone reading the answer understand filter and map! 希望这有助于任何阅读答案的人了解过滤器和地图!

You could also use a set for the filter provided you're not looking for patterns that contain repeated letters: 如果您没有查找包含重复字母的模式,您也可以使用过滤器集:

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) }

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

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