Другое

Как разделить строку в Swift на массив

Узнайте, как разбить строку в Swift на массив, используя методы components(separatedBy:) и split(), учитывая пробелы, табуляцию и специальные случаи.

Как разделить строку на массив в Swift?

У меня есть переменная строки:

swift
var fullName: String = "First Last"

Я хочу разделить эту строку по пробелу и присвоить части отдельным переменным:

swift
var fullNameArr = // Как разделить строку здесь?

var firstName: String = fullNameArr[0]
var lastName: String? = fullNameArr[1]

Кроме того, мне нужно обрабатывать случаи, когда у пользователя может не быть фамилии.

Чтобы разбить строку на массив в Swift, можно воспользоваться либо методом components(separatedBy:), либо более современным методом split(). Для вашего конкретного случая с разделением по пробелам лучше использовать встроенный набор символов whitespacesAndNewlines, который обрабатывает все типы пробелов, включая пробелы, табуляцию и разрывы строк.

Contents

Основные методы разделения строк

Самый простой способ разбить строку в Swift — использовать метод components(separatedBy:). Он делит строку на массив подстрок по указанному разделителю.

swift
var fullName: String = "First Last"
let fullNameArr = fullName.components(separatedBy: " ")
// fullNameArr == ["First", "Last"]

Однако этот простой подход имеет ограничения. Как отмечено в обсуждении на Stack Overflow, “The accepted answers don’t split by whitespace, they only split by the space character”[^1]. Это значит, что он не будет корректно обрабатывать табуляцию, перевод строки и другие пробельные символы.


Обработка различных типов пробелов

Для надёжной обработки пробелов Swift предоставляет встроенный набор символов, специально предназначенный для этой цели. По словам Zero To App Store, “Swift has a built‑in character set for this purpose. Its named whitespacesAndNewlines appropriately”[^3].

swift
var fullName: String = "First\tLast\nMiddle" // С табуляцией и переводами строки
let fullNameArr = fullName.components(separatedBy: .whitespacesAndNewlines)
// fullNameArr == ["First", "Last", "Middle"]

Набор whitespacesAndNewlines включает:

  • Пробелы (" ")
  • Табуляцию ("\t")
  • Символы перевода строки ("\n")
  • Символы возврата каретки ("\r")
  • Другие Unicode‑пробельные символы

Обработка крайних случаев (отсутствие фамилии)

При работе с пользовательским вводом необходимо обрабатывать случаи, когда пользователь не указывает фамилию. Вот как можно безопасно разбить и извлечь имена:

swift
var fullName: String = "First" // Только имя

// Разделяем по пробелам и отфильтровываем пустые строки
let nameComponents = fullName.components(separatedBy: .whitespacesAndNewlines)
    .filter { !$0.isEmpty }

var firstName: String = nameComponents.first ?? ""
var lastName: String? = nameComponents.count > 1 ? nameComponents[1] : nil

print(firstName) // "First"
print(lastName)  // nil

Для более сложных сценариев можно также использовать регулярные выражения для нормализации пробелов перед разделением:

swift
var fullName: String = "  First   Last  "
let searchTerms = fullName
    .replacingOccurrences(of: "\\s+", with: " ", options: .regularExpression)
    .trimmingCharacters(in: .whitespaces)
    .components(separatedBy: " ")

// searchTerms == ["First", "Last"]

Как показано в примере на Stack Overflow, этот подход “replaces one or more whitespace characters with a single space before splitting”[^1].


Современные подходы в Swift

Swift 4.0 представил более мощный метод split(), который обеспечивает лучший контроль над процессом разделения. По данным Apple Developer Documentation, этот метод “returns the longest possible subsequences of the collection, in order, around elements equal to the given element”[^6].

swift
let fullName: String = "First Middle Last"
let components = fullName.split(separator: " ")

let firstName = String(components[0]) // "First"
let lastName = components.count > 1 ? String(components[1]) : nil

Метод split() имеет несколько преимуществ по сравнению с components(separatedBy:):

  • Он работает быстрее с большими строками
  • Возвращает массив Substring (что более эффективно)
  • Позволяет управлять тем, будут ли пропущены пустые подстроки
  • Можно ограничить количество разделений
swift
let text = "Hello   world"
let parts = text.split(separator: " ", omittingEmptySubsequences: false)
// parts == ["Hello", "", "", "world"]

Практические примеры

Ниже приведены практические примеры для разных сценариев:

Пример 1: Простое разделение имени

swift
func splitFullName(_ fullName: String) -> (firstName: String, lastName: String?) {
    let components = fullName.components(separatedBy: .whitespacesAndNewlines)
        .filter { !$0.isEmpty }
    
    return (
        firstName: components.first ?? "",
        lastName: components.count > 1 ? components[1] : nil
    )
}

// Использование
let result = splitFullName("John Doe")
print(result.firstName) // "John"
print(result.lastName)  // "Doe"

Пример 2: Обработка нескольких средних имен

swift
func splitNameWithMultipleParts(_ fullName: String) -> (firstName: String, lastName: String?, middleNames: [String]) {
    let components = fullName.components(separatedBy: .whitespacesAndNewlines)
        .filter { !$0.isEmpty }
    
    guard !components.isEmpty else {
        return (firstName: "", lastName: nil, middleNames: [])
    }
    
    let firstName = components[0]
    let lastName = components.count > 1 ? components.last : nil
    let middleNames = components.count > 2 ? Array(components.dropFirst().dropLast()) : []
    
    return (firstName: firstName, lastName: lastName, middleNames: middleNames)
}

Пример 3: Использование регулярных выражений для сложного разделения

swift
import Foundation

let fullName: String = "  First\t\nMiddle   Last  "
let normalized = fullName
    .replacingOccurrences(of: "\\s+", with: " ", options: .regularExpression)
    .trimmingCharacters(in: .whitespaces)

let nameParts = normalized.components(separatedBy: " ")
print(nameParts) // ["First", "Middle", "Last"]

Лучшие практики

  1. Всегда обрабатывайте крайние случаи: пользователи могут вводить неполные имена, лишние пробелы или вообще не вводить имя.
  2. Используйте подходящую обработку пробелов: для пользовательского ввода используйте .whitespacesAndNewlines вместо простого " " для обработки всех типов пробелов.
  3. Фильтруйте пустые строки: применяйте .filter { !$0.isEmpty }, чтобы удалить пустые строки, возникающие из-за нескольких подряд идущих пробелов.
  4. Рассмотрите использование Substring: для критичных к производительности приложений используйте split(), который возвращает Substring вместо полных строк.
  5. Нормализуйте ввод: применяйте регулярные выражения, чтобы преобразовать несколько пробелов в один перед разделением.
  6. Предоставляйте резервные значения: всегда обрабатывайте опционалы и предоставляйте значения по умолчанию, если данные могут отсутствовать.

Совет от экспертов: Согласно Hacking with Swift, “You can convert a string to an array by breaking it up by a substring using the components(separatedBy:) method”[^2]. Это особенно полезно, когда нужно разделить строку по более чем одному пробелу.


Заключение

Разделение строк в Swift становится простым, когда вы понимаете доступные методы и их подходящие случаи использования. Ключевые выводы:

  1. Используйте components(separatedBy: .whitespacesAndNewlines) для надёжной обработки пробелов.
  2. Всегда фильтруйте пустые строки, чтобы корректно обрабатывать несколько подряд идущих пробелов.
  3. Используйте привязку опционалов для безопасной обработки случаев, когда пользователь не вводит фамилию.
  4. Учитывайте производительность при выборе между components() и split().
  5. Нормализуйте ввод с помощью регулярных выражений для сложных сценариев пробелов.

Для большинства приложений рекомендуемый подход сочетает правильную обработку пробелов с управлением крайними случаями, создавая надёжное решение для разделения имени, которое надёжно работает с пользовательским вводом.

Источники

  1. Stack Overflow – Split a String into an array in Swift?
  2. Hacking with Swift – How to split a string into an array: components(separatedBy:)
  3. Zero To App Store – How To Split A String In Swift With Examples
  4. Apple Developer Documentation – split(separator:maxSplits:omittingEmptySubsequences:)
  5. Dhiwise – Swift Split String Techniques Every Developer Should Know
  6. Sarunw – How to split string into array of substrings in Swift
Авторы
Проверено модерацией
Модерация