Avatar ·

Как разбить строку на массив в Swift? (Split String into Array)

Всем привет! Я новичок в Swift и никак не могу понять, как правильно разбить строку на массив строк. Например, у меня есть строка: ```swift let text = "яблоко,банан,апельсин,виноград" ``` Мне нужно получить массив: ```swift ["яблоко", "банан", "апельсин", "виноград"] ``` Я пробовал использовать метод `components(separatedBy:)`, но он доступен только для `NSString`. А в Swift, насколько я знаю, строки это `String`. Также я слышал про `split`, но он возвращает `Array`, а мне нужны обычные `String`, потому что я буду дальше с ними работать, передавать в функции, которые принимают `String`, а не `Substring`. Подскажите, как правильно и эффективно разбить строку на массив строк в Swift? Есть ли какой-то стандартный метод для этого? И как потом избавиться от `Substring` и получить чистые `String`? Буду благодарен за примеры кода! P.S. В будущем мне нужно будет разбивать строки и по другим разделителям, например, по пробелам или по точке с запятой. Хочется универсальный подход. <<>>

Основной способ: метод split(separator:maxSplits:omittingEmptySubsequences:)

В Swift стандартный способ разбить строку на массив — использовать метод split, который возвращает [Substring]. Это сделано для производительности: Substring — это легковесное представление, которое ссылается на исходную строку, не копируя данные. Если вам нужны именно String, просто преобразуйте результат с помощью map(String.init).

Пример для вашего случая (разделитель — запятая):

let text = "яблоко,банан,апельсин,виноград"
let fruits = text.split(separator: ",").map(String.init)
print(fruits) // ["яблоко", "банан", "апельсин", "виноград"]

Пошаговое объяснение:

  • text.split(separator: ",") — разбивает строку по запятой, возвращает [Substring].
  • .map(String.init) — преобразует каждый Substring в новую строку String.

Дополнительные параметры split

Метод split имеет несколько полезных параметров:

  • maxSplits: Int — максимальное количество разбиений. По умолчанию Int.max (неограниченно).
  • omittingEmptySubsequences: Bool — если true (по умолчанию), пустые части не включаются. Если нужно сохранить пустые элементы, поставьте false.

Пример с пробелами и ограничением:

let sentence = "Swift  язык  программирования"
let words = sentence.split(separator: " ", maxSplits: 2, omittingEmptySubsequences: false).map(String.init)
print(words) // ["Swift", "", "язык  программирования"]

Обратите внимание: maxSplits: 2 означает, что будет выполнено не более 2 разбиений, поэтому последняя часть содержит остаток строки.

Альтернатива: components(separatedBy:) из Foundation

Если вам нужна обратная совместимость или вы привыкли к Objective-C, можно использовать components(separatedBy:) из Foundation. Этот метод возвращает [String] сразу:

import Foundation

let text = "яблоко,банан,апельсин,виноград"
let fruits = text.components(separatedBy: ",")
print(fruits) // ["яблоко", "банан", "апельсин", "виноград"]

⚠️ Важно: components(separatedBy:) ведёт себя иначе, чем split:

  • Он всегда включает пустые строки (например, для строки "a,,b" вернёт ["a", "", "b"]).
  • Он работает только с одним разделителем (не поддерживает Set символов).
  • Он менее производительный, чем split, так как сразу создаёт String.

Разбиение по набору символов

Если нужно разбить по нескольким разделителям (например, по запятой и точке с запятой), используйте split с CharacterSet:

let messyText = "яблоко;банан,апельсин;виноград"
let separatorSet = CharacterSet(charactersIn: ",;")
let items = messyText.components(separatedBy: separatorSet) // Foundation
// или
let items2 = messyText.unicodeScalars.split { separatorSet.contains($0) }.map(String.init) // Swift native

Итоговая рекомендация

Для большинства случаев используйте split с map(String.init) — это быстро, эффективно и современно. Если вам нужно точное поведение как в Objective-C (с пустыми элементами), используйте components(separatedBy:) из Foundation. Не забывайте импортировать Foundation при необходимости.

<<>>

Разбиение с помощью регулярных выражений (NSRegularExpression)

Если ваши разделители сложнее, чем один символ (например, нужно разбить по слову "и" или по знакам препинания), можно использовать регулярные выражения. Это даёт максимальную гибкость, но требует осторожности с производительностью.

Пример: разбить по пробелам и знакам препинания

import Foundation

let text = "Привет, мир! Как дела?"
let pattern = "[\\s,?!]+" // один или более пробелов или знаков препинания
let regex = try! NSRegularExpression(pattern: pattern)
let range = NSRange(text.startIndex..., in: text)
let matches = regex.matches(in: text, range: range)

var result: [String] = []
var currentIndex = text.startIndex
for match in matches {
    let partRange = currentIndex..

Этот способ полезен для сложной логики разбиения, но для простых случаев лучше использовать split или components — они читаемее и быстрее.