Swift -在[String]数组中查找最长字符串的最佳实践

chhqkbe1  于 2023-03-17  发布在  Swift
关注(0)|答案(6)|浏览(154)

我试图找到在字符串数组中获取最长字符串的最有效方法。例如:

let array = ["I'm Roi","I'm asking here","Game Of Thrones is just good"]

结果是-"Game Of Thrones is just good"
我试过使用maxElement函数,但它给予了字母表中的最大字符串(maxElement())。

有什么建议吗?谢谢!

disbfnqx

disbfnqx1#

为了获得好的排序结果,不要使用 O(n log(n)) 的排序方法,而是使用max(by:),它在Array上是 O(n),为它提供了一个闭包来比较字符串长度:

雨燕4:

对于Swift 4,可以使用String上的count属性获取字符串长度:

let array = ["I'm Roi","I'm asking here","Game Of Thrones is just good"]

if let max = array.max(by: {$1.count > $0.count}) {
    print(max)
}

雨燕3:

String上使用.characters.count以获得字符串长度:

let array = ["I'm Roi","I'm asking here","Game Of Thrones is just good"]

if let max = array.max(by: {$1.characters.count > $0.characters.count}) {
    print(max)
}

雨燕2:

在Array上使用maxElement,为它提供闭包以比较字符串长度:

let array = ["I'm Roi","I'm asking here","Game Of Thrones is just good"]

if let max = array.maxElement({$1.characters.count > $0.characters.count}) {
    print(max)
}

注意:maxElementO(n)。一个好的排序是 O(n log(n)),所以对于大型数组,这将比排序快得多。

wko9yo5t

wko9yo5t2#

你可以使用reduce来完成这个任务,它将遍历你的数组,跟踪当前最长的字符串,然后在完成时返回它。
例如:

let array = ["I'm Roi","I'm asking here","Game Of Thrones is just good"]

if let longestString = array.reduce(Optional<String>.None, combine:{$0?.characters.count > $1.characters.count ? $0:$1}) {
    print(longestString) // "Game Of Thrones is just good"
}

(Note Optional.None在Swift中现在是Optional.none 3)
它使用一个nil起始值来说明数组可能为空的事实,正如@JHZ所指出的(在这种情况下它将返回nil)。如果你知道你的数组至少有一个元素,你可以将它简化为:

let longestString = array.reduce("") {$0.characters.count > $1.characters.count ? $0:$1}

因为它只对每个元素迭代一次,所以比使用sort()要快。我做了一个快速的基准测试,sort()看起来慢了大约20倍(虽然没有过早优化的必要,但我觉得值得一提)。

**编辑:**我建议你使用@vacawama的解决方案,因为它甚至比reduce更干净!

xghobddn

xghobddn3#

给你:

let array = ["I'm Roi","I'm asking here","Game Of Thrones is just good"]

var sortedArr = array.sort() { $0.characters.count > $1.characters.count }

let longestEelement = sortedArr[0]
xlpyo6sf

xlpyo6sf4#

您还可以通过创建以下函数来练习泛型的使用:

func longestString<T:Sequence>(from stringsArray: T) -> String where T.Iterator.Element == String{
    return (stringsArray.max {$0.count < $1.count}) ?? ""
}

说明:创建一个名为longestString的函数,声明有一个实现Sequence协议的泛型类型T(Sequence定义如下:这个函数将返回一个String(当然是最长的),where子句解释了泛型类型T应该被限制为具有String类型的元素。
在函数内部,通过比较stringsArray中元素的最长字符串来调用其max函数。将返回最长字符串(可选,因为如果数组为空,则可以为nil)。如果最长字符串为nil,则(使用??)返回空字符串作为最长字符串。
现在叫它:

let longestA = longestString(from:["Shekinah", "Chesedh", "Agape Sophia"])

如果你掌握了使用泛型的窍门,即使字符串隐藏在对象中,你也可以使用上面的编码模式,你可以将元素改为同一个类的对象(例如Person)。
因此:

class Person {
    let name: String
    init(name: String){
        self.name = name
    }
}

func longestName<T:Sequence>(from stringsArray: T) -> String where T.Iterator.Element == Person{
    return (stringsArray.max {$0.name.count < $1.name.count})?.name ?? ""
}

然后像这样调用函数:

let longestB = longestName(from:[Person(name: "Shekinah"), Person(name: "Chesedh"), Person(name: "Agape Sophia")])

你还可以根据函数的使用情况来重命名函数;你可以调整模式来返回其他内容,比如对象本身,或者String的长度(计数);最后,熟悉泛型可以提高你的编码能力。
现在,再做一点调整,您可以进一步扩展,以便可以比较许多不同类型所拥有的字符串,只要它们实现了一个公共协议。

protocol Nameable {
    var name: String {get}
}

这定义了一个名为Nameable的协议,它要求实现者拥有一个String类型的name变量。接下来,我们定义两个不同的东西来实现该协议。

class Person: Nameable {
    let name: String
    init(name: String){
        self.name = name
    }
}

struct Pet: Nameable {
    let name: String
}

然后我们调整泛型函数,使其要求元素必须符合Namable,尽管它们有很大的不同。

func longestName<T:Sequence>(from stringsArray: T) -> String where T.Iterator.Element == Nameable{
return (stringsArray.max {$0.name.count < $1.name.count})?.name ?? ""
}

让我们把不同的对象集合到一个数组中,然后调用我们的函数。

let myFriends: [Nameable] = [Pet(name: "Bailey"), Person(name: "Agape Sophia")]

let longestC = longestName(from: myFriends)

最后,在知道上面的“where”和“Sequence”之后,您可以简单地扩展Sequence:

extension Sequence where Iterator.Element == String {

    func topString() -> String {
        self.max(by: { $0.count < $1.count }) ?? ""
    }
}

或协议类型:

extension Sequence where Iterator.Element == Nameable {
    func theLongestName() -> Nameable? {
        self.max(by: { $0.name.count < $1.name.count })
    }
}
ebdffaop

ebdffaop5#

@vacawama是一个很好的字符串,但是需要考虑的一点是,你可能有多个相同长度的元素,所以结果是:“get the longest string in a string array”可以是多个长度相同的字符串,如果是这样的话,可以这样做:

if let max = array.max(by: {$1.count > $0.count}) {
    let largeStrings = array.filter{$0.count == max.count}
    print(largeStrings)
}
8wtpewkr

8wtpewkr6#

这里我们可以通过简单地遍历数组并检查每个项目串的计数,并将最长的项目串及其计数存储在临时变量中来完成,时间复杂度为O(n)。
let array = [“我是Roi”,“我在这里问”,“权力的游戏刚刚好”]

// create var for storing longest str
var str : String = ""
var strCount : Int = 0

for item in array {
    if item.count > strCount {
        strCount = item.count
        str = item
    }
}

print(str)
print(strCount)

相关问题