从Swift中删除字符串中第一个字符最简洁的方法是什么?

SSt*_*eve 107 string swift

我想从字符串中删除第一个字符.到目前为止,我提出的最简洁的事情是:

display.text = display.text!.substringFromIndex(advance(display.text!.startIndex, 1))
Run Code Online (Sandbox Code Playgroud)

我知道我们不能使用IntUnicode 来索引字符串,但是这个解决方案看起来非常冗长.还有另一种我忽视的方式吗?

Mic*_*lum 193

如果您使用的是Swift 3,则可以忽略此答案的第二部分.好消息是,现在这又是简洁的!只使用String的新删除(at :)方法.

var myString = "Hello, World"
myString.remove(at: myString.startIndex)

myString // "ello, World"
Run Code Online (Sandbox Code Playgroud)

我喜欢这个的全局dropFirst()功能.

let original = "Hello" // Hello
let sliced = dropFirst(original) // ello
Run Code Online (Sandbox Code Playgroud)

它简洁明了,适用于任何符合Sliceable协议的东西.

如果你使用的是Swift 2,这个答案已经改变了.您仍然可以使用dropFirst,但不能从string characters属性中删除第一个字符,然后将结果转换回String.dropFirst也成为一种方法,而不是一种功能.

let original = "Hello" // Hello
let sliced = String(original.characters.dropFirst()) // ello
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用后缀函数来拼接字符串UTF16View.当然,之后也必须将其转换回String.

let original = "Hello" // Hello
let sliced = String(suffix(original.utf16, original.utf16.count - 1)) // ello
Run Code Online (Sandbox Code Playgroud)

所有这一切都说明我最初提供的解决方案并不是最新版Swift中最简洁的方法.removeAtIndex()如果您正在寻找一个简短直观的解决方案,我建议您使用@chris的解决方案.

var original = "Hello" // Hello
let removedChar = original.removeAtIndex(original.startIndex)

original // ello
Run Code Online (Sandbox Code Playgroud)

正如@vacawama在下面的评论中所指出的,另一个不修改原始String的选项是使用substringFromIndex.

let original = "Hello" // Hello
let substring = original.substringFromIndex(advance(original.startIndex, 1)) // ello
Run Code Online (Sandbox Code Playgroud)

或者,如果您正在寻找从字符串的开头和结尾删除字符,则可以使用substringWithRange.只要务必防范这种情况startIndex + n > endIndex - m.

let original = "Hello" // Hello

let newStartIndex = advance(original.startIndex, 1)
let newEndIndex = advance(original.endIndex, -1)

let substring = original.substringWithRange(newStartIndex..<newEndIndex) // ell
Run Code Online (Sandbox Code Playgroud)

最后一行也可以使用下标表示法编写.

let substring = original[newStartIndex..<newEndIndex]
Run Code Online (Sandbox Code Playgroud)

  • 很棒的答案!我认为值得注意的是`remove(at:)`方法的返回值:它是删除的字符,而不是新的字符串.例如,`let removedCharacter = myString.remove(at:myString.startIndex)`.我错误地返回了方法调用的结果,忘记了这种情况就是这种情况.快乐编码全部! (3认同)
  • 它并不要求你进入基金会世界. (2认同)
  • 它非常迅速/ fp. (2认同)

vac*_*ama 105

Swift 4的更新

在Swift 4中,再次String符合Collection,因此可以使用dropFirstdropLast修剪字符串的开头和结尾.结果是类型Substring,所以你需要将它传递给String构造函数以获取String:

let str = "hello"
let result1 = String(str.dropFirst())    // "ello"
let result2 = String(str.dropLast())     // "hell"
Run Code Online (Sandbox Code Playgroud)

dropFirst()并且dropLast()还要Int指定要删除的字符数:

let result3 = String(str.dropLast(3))    // "he"
let result4 = String(str.dropFirst(4))   // "o"
Run Code Online (Sandbox Code Playgroud)

如果指定要删除的字符数多于字符串中的字符数,则结果将为空字符串("").

let result5 = String(str.dropFirst(10))  // ""
Run Code Online (Sandbox Code Playgroud)

Swift 3的更新

如果您只想删除第一个字符并想要更改原始字符串,请参阅@ MickMacCallum的答案.如果要在过程中创建新字符串,请使用substring(from:).通过扩展String,您可以隐藏丑陋substring(from:)substring(to:)创建有用的附加内容来修剪一个开头和结尾String:

extension String {
    func chopPrefix(_ count: Int = 1) -> String {
        return substring(from: index(startIndex, offsetBy: count))
    }

    func chopSuffix(_ count: Int = 1) -> String {
        return substring(to: index(endIndex, offsetBy: -count))
    }
}

"hello".chopPrefix()    // "ello"
"hello".chopPrefix(3)   // "lo"

"hello".chopSuffix()    // "hell"
"hello".chopSuffix(3)   // "he"
Run Code Online (Sandbox Code Playgroud)

喜欢dropFirstdropLast他们之前,这些功能会崩溃如果没有在字符串提供足够的字母.调用者有责任正确使用它们.这是一个有效的设计决策.可以写它们来返回一个可选项,然后调用者必须将其解包.


Swift 2.x

可惜在斯威夫特2,dropFirstdropLast(之前的最佳解决方案)并不像他们以前那样方便.通过扩展String,您可以隐藏丑陋substringFromIndexsubstringToIndex:

extension String {
    func chopPrefix(count: Int = 1) -> String {
         return self.substringFromIndex(advance(self.startIndex, count))
    }

    func chopSuffix(count: Int = 1) -> String {
        return self.substringToIndex(advance(self.endIndex, -count))
    }
}

"hello".chopPrefix()    // "ello"
"hello".chopPrefix(3)   // "lo"

"hello".chopSuffix()    // "hell"
"hello".chopSuffix(3)   // "he"
Run Code Online (Sandbox Code Playgroud)

喜欢dropFirstdropLast他们之前,这些功能会崩溃如果没有在字符串提供足够的字母.调用者有责任正确使用它们.这是一个有效的设计决策.可以写它们来返回一个可选项,然后调用者必须将其解包.


Swift 1.2中,你需要chopPrefix像这样调用:

"hello".chopPrefix(count: 3)  // "lo"
Run Code Online (Sandbox Code Playgroud)

或者您可以_在函数定义中添加下划线以抑制参数名称:

extension String {
    func chopPrefix(_ count: Int = 1) -> String {
         return self.substringFromIndex(advance(self.startIndex, count))
    }

    func chopSuffix(_ count: Int = 1) -> String {
        return self.substringToIndex(advance(self.endIndex, -count))
    }
}
Run Code Online (Sandbox Code Playgroud)

  • Swift的内置字符串操作有多复杂,我仍然感到震惊.我的意思是这是基本的,基本的东西; 它应该看起来不像我正在实现一个解析器.感谢您的扩展,以简化此操作.令人困惑的是Apple不会只是将它添加到String类中!也许它还有很大的变化. (3认同)

Jal*_*zir 16

Swift 2.2

'advance'不可用:在索引上调用'advancedBy(n)'方法

    func chopPrefix(count: Int = 1) -> String {
        return self.substringFromIndex(self.startIndex.advancedBy(count))
    }

    func chopSuffix(count: Int = 1) -> String {
        return self.substringFromIndex(self.endIndex.advancedBy(count))
    }
Run Code Online (Sandbox Code Playgroud)

Swift 3.0

    func chopPrefix(_ count: Int = 1) -> String {
        return self.substring(from: self.characters.index(self.startIndex, offsetBy: count))
    }

    func chopSuffix(_ count: Int = 1) -> String {
       return self.substring(to: self.characters.index(self.endIndex, offsetBy: -count))
    }
Run Code Online (Sandbox Code Playgroud)

Swift 3.2

字符串内容视图为字符集合.

@available(swift, deprecated: 3.2, message: "Please use String or Substring directly")
public var characters: String.CharacterView
Run Code Online (Sandbox Code Playgroud)
func chopPrefix(_ count: Int = 1) -> String {
    if count >= 0 && count <= self.count {
        return self.substring(from: String.Index(encodedOffset: count))
    }
    return ""
}

func chopSuffix(_ count: Int = 1) -> String {
    if count >= 0 && count <= self.count {
        return self.substring(to: String.Index(encodedOffset: self.count - count))
    }
    return ""
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特4

extension String {

    func chopPrefix(_ count: Int = 1) -> String {
        if count >= 0 && count <= self.count {
            let indexStartOfText = self.index(self.startIndex, offsetBy: count)
            return String(self[indexStartOfText...])
        }
        return ""
    }

    func chopSuffix(_ count: Int = 1) -> String {
        if count >= 0 && count <= self.count {
            let indexEndOfText = self.index(self.endIndex, offsetBy: -count)
            return String(self[..<indexEndOfText])
        }
        return ""
    }
}
Run Code Online (Sandbox Code Playgroud)


jrc*_*jrc 12

在Swift 2中,执行以下操作:

let cleanedString = String(theString.characters.dropFirst())
Run Code Online (Sandbox Code Playgroud)

我推荐https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-string-api-so-hard.html来了解Swift字符串.


jas*_*n z 8

取决于你想要的最终结果是什么(变异与非变异).

从Swift 4.1开始:

变异:

var str = "hello"
str.removeFirst() // changes str 
Run Code Online (Sandbox Code Playgroud)

Nonmutating:

let str = "hello"
let strSlice = str.dropFirst() // makes a slice without the first letter
let str2 = String(strSlice)
Run Code Online (Sandbox Code Playgroud)

笔记:

  • nonmutating为清楚起见,我在示例中添加了一个额外的步骤.主观上,结合最后两个步骤将更简洁.
  • 命名dropFirst对我来说似乎有点奇怪,因为如果我正确理解Swift API设计指南,那dropFirst应该是dropingFirst因为它是非突变的.只是一个想法 :).


chr*_*ris 6

那这个呢?

s.removeAtIndex(s.startIndex)
Run Code Online (Sandbox Code Playgroud)

这当然假设你的字符串是可变的.它返回已删除的字符,但会更改原始字符串.


Byt*_*ger 6

前面的答案非常好,但是到目前为止,我认为这可能是在Swift 4中从字符串中删除第一个字符的最简洁的方法:

var line: String = "This is a string..."
var char: Character? = nil

char = line.removeFirst()

print("char = \(char)")  // char = T
print("line = \(line)")  // line = his is a string ...
Run Code Online (Sandbox Code Playgroud)