Разбить строку в массив в Swift?

Скажем, у меня есть строка:

var fullName: String = "First Last"

Я хочу разбить базу строк на пробел и присвоить значения их соответствующим переменным

var fullNameArr = // something like: fullName.explode(" ") 

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

Кроме того, иногда пользователи могут не иметь фамилии.

Ответ 1

Способ Swift - использовать глобальную функцию split, например:

var fullName = "First Last"
var fullNameArr = split(fullName) {$0 == " "}
var firstName: String = fullNameArr[0]
var lastName: String? = fullNameArr.count > 1 ? fullNameArr[1] : nil

с Swift 2

В Swift 2 использование split становится немного более сложным из-за введения внутреннего типа CharacterView. Это означает, что String больше не использует протоколы SequenceType или CollectionType, и вместо этого вы должны использовать свойство .characters для доступа к представлению типа CharacterView экземпляра String. (Примечание: CharacterView использует протоколы SequenceType и CollectionType).

let fullName = "First Last"
let fullNameArr = fullName.characters.split{$0 == " "}.map(String.init)
// or simply:
// let fullNameArr = fullName.characters.split{" "}.map(String.init)

fullNameArr[0] // First
fullNameArr[1] // Last 

Ответ 2

Просто наберите componentsSeparatedByString метод fullName

import Foundation

var fullName: String = "First Last"
let fullNameArr = fullName.componentsSeparatedByString(" ")

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

Обновление для Swift 3 +

import Foundation

let fullName    = "First Last"
let fullNameArr = fullName.components(separatedBy: " ")

let name    = fullNameArr[0]
let surname = fullNameArr[1]

Ответ 3

Самый простой способ сделать это - использовать компонентыSeparatedBy:

Для Swift 2:

import Foundation
let fullName : String = "First Last";
let fullNameArr : [String] = fullName.componentsSeparatedByString(" ")

// And then to access the individual words:

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

Для Swift 3:

import Foundation

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

// And then to access the individual words:

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

Ответ 4

Swift Dev. 4.0 (24 мая 2017 года)

Новая функция split в Swift 4 (Бета).

import Foundation
let sayHello = "Hello Swift 4 2017";
let result = sayHello.split(separator: " ")
print(result)

Вывод:

["Hello", "Swift", "4", "2017"]

Доступ к значениям:

print(result[0]) // Hello
print(result[1]) // Swift
print(result[2]) // 4
print(result[3]) // 2017

Xcode 8.1/Swift 3.0.1

Вот несколько разграничителей с массивом.

import Foundation
let mathString: String = "12-37*2/5"
let numbers = mathString.components(separatedBy: ["-", "*", "/"])
print(numbers)

Вывод:

["12", "37", "2", "5"]

Ответ 5

В качестве альтернативы ответу WMios вы также можете использовать componentsSeparatedByCharactersInSet, что может быть удобно в случае, если у вас больше разделителей (пробел, запятая и т.д.).

С вашим конкретным вводом:

let separators = NSCharacterSet(charactersInString: " ")
var fullName: String = "First Last";
var words = fullName.componentsSeparatedByCharactersInSet(separators)

// words contains ["First", "Last"]

Использование нескольких разделителей:

let separators = NSCharacterSet(charactersInString: " ,")
var fullName: String = "Last, First Middle";
var words = fullName.componentsSeparatedByCharactersInSet(separators)

// words contains ["Last", "First", "Middle"]

Ответ 6

Swift 4 или более поздняя версия

Если вам просто нужно правильно отформатировать имя человека, вы можете использовать PersonNameComponentsFormatter.

Класс PersonNameComponentsFormatter обеспечивает локализованный представления компонентов имени человека, как представлено объектом PersonNameComponents. Используйте этот класс для создания локализованного имена при отображении информации об имени человека для пользователя.


// iOS (9.0 and later), macOS (10.11 and later), tvOS (9.0 and later), watchOS (2.0 and later)
let nameFormatter = PersonNameComponentsFormatter()

let name =  "Mr. Steven Paul Jobs Jr."
// personNameComponents requires iOS (10.0 and later)
if let nameComps  = nameFormatter.personNameComponents(from: name) {
    nameComps.namePrefix   // Mr.
    nameComps.givenName    // Steven
    nameComps.middleName   // Paul
    nameComps.familyName   // Jobs
    nameComps.nameSuffix   // Jr.

    // It can also be configured to format your names
    // Default (same as medium), short, long or abbreviated

    nameFormatter.style = .default
    nameFormatter.string(from: nameComps)   // "Steven Jobs"

    nameFormatter.style = .short
    nameFormatter.string(from: nameComps)   // "Steven"

    nameFormatter.style = .long
    nameFormatter.string(from: nameComps)   // "Mr. Steven Paul Jobs jr."

    nameFormatter.style = .abbreviated
    nameFormatter.string(from: nameComps)   // SJ

    // It can also be use to return an attributed string using annotatedString method
    nameFormatter.style = .long
    nameFormatter.annotatedString(from: nameComps)   // "Mr. Steven Paul Jobs jr."
}

enter image description here

редактировать/обновление:

Swift 5 или более поздняя версия

Для простого разбиения строки не буквенными символами мы можем использовать новое свойство Character isLetter:

let fullName = "First Last"

let components = fullName.split{ !$0.isLetter }
print(components)  // "["First", "Last"]\n"

Ответ 7

Swift 4

let words = "these words will be elements in an array".components(separatedBy: " ")

Ответ 8

Пробел

Как правило, люди повторно изобретают эту проблему и плохие решения снова и снова. Это пространство? "" и как насчет "\n", "\ t" или некоторого символа пробела в unicode, который вы никогда не видели, в немалой степени, потому что он невидим. Пока вы можете уйти с

Слабое решение

import Foundation
let pieces = "Mary had little lamb".componentsSeparatedByString(" ")

Если вам когда-либо понадобится трястись от реальности, посмотрите видео WWDC на строках или датах. Короче говоря, почти всегда лучше позволить Apple решить эту мирскую задачу.

Надежное решение: используйте NSCharacterSet

Способ сделать это правильно, IMHO, заключается в использовании NSCharacterSet поскольку, как было сказано ранее, ваши пробелы могут быть не такими, какие вы ожидаете, и Apple предоставила набор символов в виде пробелов. Чтобы изучить различные предоставленные наборы символов, ознакомьтесь с документацией разработчика Apple NSCharacterSet, а затем, только тогда, добавьте или создайте новый набор символов, если он не соответствует вашим потребностям.

Пробелы NSCharacterSet

Возвращает набор символов, содержащий символы в Unicode General Category Zs и CHARACTER TABULATION (U + 0009).

let longerString: String = "This is a test of the character set splitting system"
let components = longerString.components(separatedBy: .whitespaces)
print(components)

Ответ 9

В Swift 4.2 и Xcode 10

//This is your str
let str = "This is my String" //Here replace with your string

Опция 1

let items = str.components(separatedBy: " ")//Here replase space with your value and the result is Array.
//Direct single line of code
//let items = "This is my String".components(separatedBy: " ")
let str1 = items[0]
let str2 = items[1]
let str3 = items[2]
let str4 = items[3]
//OutPut
print(items.count)
print(str1)
print(str2)
print(str3)
print(str4)
print(items.first!)
print(items.last!)

Вариант 2

let items = str.split(separator: " ")
let str1 = String(items.first!)
let str2 = String(items.last!)
//Output
print(items.count)
print(items)
print(str1)
print(str2)

Вариант 3

let arr = str.split {$0 == " "}
print(arr)

Вариант 4

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

По документации Apple...

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
// Prints "["BLANCHE:", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

print(line.split(separator: " ", maxSplits: 1))//This can split your string into 2 parts
// Prints "["BLANCHE:", "  I don\'t want realism. I want magic!"]"

print(line.split(separator: " ", maxSplits: 2))//This can split your string into 3 parts

print(line.split(separator: " ", omittingEmptySubsequences: false))//array contains empty strings where spaces were repeated.
// Prints "["BLANCHE:", "", "", "I", "don\'t", "want", "realism.", "I", "want", "magic!"]"

print(line.split(separator: " ", omittingEmptySubsequences: true))//array not contains empty strings where spaces were repeated.
print(line.split(separator: " ", maxSplits: 4, omittingEmptySubsequences: false))
print(line.split(separator: " ", maxSplits: 3, omittingEmptySubsequences: true))

Ответ 10

Swift 4 упрощает разделение символов, просто используйте новую функцию разделения для строк.

Пример: let s = "hi, hello" let a = s.split(separator: ",") print(a)

Теперь у вас есть массив с "привет" и "привет".

Ответ 11

Swift 3

let line = "AAA    BBB\t CCC"
let fields = line.components(separatedBy: .whitespaces).filter {!$0.isEmpty}
  • Возвращает три строки AAA, BBB и CCC
  • Фильтрует пустые поля
  • Обрабатывает несколько пробелов и символы табуляции
  • Если вы хотите обрабатывать новые строки, замените .whitespaces на .whitespacesAndNewlines

Ответ 12

Xcode 8.0/Swift 3

let fullName = "First Last"
var fullNameArr = fullName.components(separatedBy: " ")

var firstname = fullNameArr[0] // First
var lastname = fullNameArr[1] // Last

Длинный путь:

var fullName: String = "First Last"
fullName += " " // this will help to see the last word

var newElement = "" //Empty String
var fullNameArr = [String]() //Empty Array

for Character in fullName.characters {
    if Character == " " {
        fullNameArr.append(newElement)
        newElement = ""
    } else {
        newElement += "\(Character)"
    }
}


var firsName = fullNameArr[0] // First
var lastName = fullNameArr[1] // Last

Ответ 13

Обновление Swift 4, Xcode 10 и iOS 12 на 100% работает

let fullName = "First Last"    
let fullNameArr = fullName.components(separatedBy: " ")
let firstName = fullNameArr[0] //First
let lastName = fullNameArr[1] //Last

См. документацию Apple здесь для получения дополнительной информации.

Ответ 14

У меня был сценарий, в котором несколько символов управления могут присутствовать в строке, которую я хочу разбить. Вместо того, чтобы поддерживать массив из них, я просто позволяю Apple обрабатывать эту часть.

Следующее работает с Swift 3.0.1 на iOS 10:

let myArray = myString.components(separatedBy: .controlCharacters)

Ответ 15

Я нашел интересный случай, что

метод 1

var data:[String] = split( featureData ) { $0 == "\u{003B}" }

Когда я использовал эту команду для разделения некоторого символа на данные, загруженные с сервера, он может разделиться во время тестирования в симуляторе и синхронизировать с тестовым устройством, но он не будет разбиваться на публикацию приложения, и Ad Hoc

Мне нужно много времени, чтобы отслеживать эту ошибку, она может быть проклята из некоторой версии Swift или некоторой версии iOS или ни

Это тоже не код HTML, так как я пытаюсь stringByRemovingPercentEncoding и он все еще не работает

дополнение 10/10/2015

в Swift 2.0 этот метод был изменен на

var data:[String] = featureData.split {$0 == "\u{003B}"}

метод 2

var data:[String] = featureData.componentsSeparatedByString("\u{003B}")

Когда я использовал эту команду, , он может разделить те же данные, которые загружаются с сервера правильно


Заключение, я действительно предлагаю использовать метод 2

string.componentsSeparatedByString("")

Ответ 16

Большинство этих ответов предполагают, что вход содержит пробел - не белый пробел и одно место в нем. Если вы можете смело сделать это предположение, тогда принятый ответ (от bennett) довольно изящный, а также метод, с которым я буду работать, когда смогу.

Если мы не сможем сделать это предположение, более надежное решение должно охватывать следующие сообщения, которые большинство ответов здесь не учитывают:

  • вкладки/новые строки/пробелы (пробелы), включая повторяющиеся символы
  • ведущие/конечные пробелы
  • Apple/Linux (\n) и символы новой строки Windows (\r\n)

Чтобы охватить эти случаи, это решение использует regex для преобразования всех пробелов (включая повторяющиеся символы и символы новой строки Windows) в одно пространство, обрезает, а затем разбивается на одно пространство:

Swift 3:

let searchInput = "  First \r\n \n \t\t\tMiddle    Last "
let searchTerms = searchInput 
    .replacingOccurrences(
        of: "\\s+",
        with: " ",
        options: .regularExpression
    )
    .trimmingCharacters(in: .whitespaces)
    .components(separatedBy: " ")

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

Ответ 17

Обновление для Swift 5 и простой способ

let paragraph = "Bob hit a ball, the hit BALL flew far after it was hit. Hello! Hie, How r u?"

let words = paragraph.components(separatedBy: [",", " ", "!",".","?"])

Это печатает,

["Bob", "hit", "a", "ball", "", "the", "hit", "BALL", "flew", "far", "after", "it", "was", "hit", "", "Hello", "", "Hie", "", "How", "r", "u", ""]

Однако если вы хотите отфильтровать пустую строку,

let words = paragraph.components(separatedBy: [",", " ", "!",".","?"]).filter({!$0.isEmpty})

выход,

["Bob", "hit", "a", "ball", "the", "hit", "BALL", "flew", "far", "after", "it", "was", "hit", "Hello", "Hie", "How", "r", "u"]

Но убедитесь, что Фонд импортирован

Ответ 18

Или без закрытия вы можете сделать это только в Swift 2:

let fullName = "First Last"
let fullNameArr = fullName.characters.split(" ")
let firstName = String(fullNameArr[0])

Ответ 19

Действия по разбиению строки на массив в Swift 4.

  1. назначить строку
  2. на основе @расщепления.

Примечание. VariableName.components(separaBy: "ключевое слово split")

let fullName: String = "First Last @ triggerd event of the session by session storage @ it can be divided by the event of the trigger."
let fullNameArr = fullName.components(separatedBy: "@")
print("split", fullNameArr)

Ответ 20

Swift 4

let string = "loremipsum.dolorsant.amet:"

let result = string.components(separatedBy: ".")

print(result[0])
print(result[1])
print(result[2])
print("total: \(result.count)")

Выход

loremipsum
dolorsant
amet:
total: 3

Ответ 21

Скажем, у вас есть переменная с именем "Hello World", и если вы хотите разбить ее и сохранить ее на две разные переменные, вы можете использовать вот так:

var fullText = "Hello World"
let firstWord = fullText.text?.components(separatedBy: " ").first
let lastWord = fullText.text?.components(separatedBy: " ").last

Ответ 22

let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]

Xcode 7.2 (7C68)

Ответ 23

Swift 2.2 Обработка ошибок и capizedizedString Добавлено:

func setFullName(fullName: String) {
    var fullNameComponents = fullName.componentsSeparatedByString(" ")

    self.fname = fullNameComponents.count > 0 ? fullNameComponents[0]: ""
    self.sname = fullNameComponents.count > 1 ? fullNameComponents[1]: ""

    self.fname = self.fname!.capitalizedString
    self.sname = self.sname!.capitalizedString
}

Ответ 24

Обработка строк по-прежнему является проблемой в Swift, и она продолжает меняться значительно, как вы можете видеть из других ответов. Надеюсь, все успокоится, и это станет проще. Это способ сделать это с текущей версией 3.0 версии Swift с несколькими символами разделителя.

Swift 3:

let chars = CharacterSet(charactersIn: ".,; -")
let split = phrase.components(separatedBy: chars)

// Or if the enums do what you want, these are preferred. 
let chars2 = CharacterSet.alphaNumerics // .whitespaces, .punctuation, .capitalizedLetters etc
let split2 = phrase.components(separatedBy: chars2)

Ответ 25

Я искал рыхлый раскол, например, PHP explode когда пустые последовательности включены в результирующий массив, это сработало для меня:

"First ".split(separator: " ", maxSplits: 1, omittingEmptySubsequences: false)

Выход:

["First", ""]

Ответ 26

Это снова изменилось в бета-версии 5. Weee! Теперь это метод в CollectionType

Старый:

var fullName = "First Last"
var fullNameArr = split(fullName) {$0 == " "}

Новое:

var fullName = "First Last"
var fullNameArr = fullName.split {$0 == " "}

Заметки о выпуске яблок

Ответ 27

Для быстрого 2, XCode 7.1:

let complete_string:String = "Hello world"
let string_arr =  complete_string.characters.split {$0 == " "}.map(String.init)
let hello:String = string_arr[0]
let world:String = string_arr[1]

Ответ 28

Вот алгоритм, который я только что создаю, который разбивает String на любой Character из массива, и если есть желание сохранить подстроки с разделенными символами, можно установить параметр swallow в true.

Xcode 7.3 - Swift 2.2:

extension String {

    func splitBy(characters: [Character], swallow: Bool = false) -> [String] {

        var substring = ""
        var array = [String]()
        var index = 0

        for character in self.characters {

            if let lastCharacter = substring.characters.last {

                // swallow same characters
                if lastCharacter == character {

                    substring.append(character)

                } else {

                    var shouldSplit = false

                    // check if we need to split already
                    for splitCharacter in characters {
                        // slit if the last character is from split characters or the current one
                        if character == splitCharacter || lastCharacter == splitCharacter {

                            shouldSplit = true
                            break
                        }
                    }

                    if shouldSplit {

                        array.append(substring)
                        substring = String(character)

                    } else /* swallow characters that do not equal any of the split characters */ {

                        substring.append(character)
                    }
                }
            } else /* should be the first iteration */ {

                substring.append(character)
            }

            index += 1

            // add last substring to the array
            if index == self.characters.count {

                array.append(substring)
            }
        }

        return array.filter {

            if swallow {

                return true

            } else {

                for splitCharacter in characters {

                    if $0.characters.contains(splitCharacter) {

                        return false
                    }
                }
                return true
            }
        }
    }
}

Пример:

"test text".splitBy([" "]) // ["test", "text"]
"test++text--".splitBy(["+", "-"], swallow: true) // ["test", "++" "text", "--"]

Ответ 29

Согласно Swift 2.2

Вы просто пишете 2 строки кода, и вы получите разделительную строку.

let fullName = "FirstName LastName"
var splitedFullName = fullName.componentsSeparatedByString(" ")
print(splitedFullName[0])
print(splitedFullName[1]) 

Enjoy.:)

Ответ 30

Я не нашел решение, которое обрабатывало бы имена с 3 или более компонентами и поддерживало бы более старые версии iOS.

struct NameComponentsSplitter {

    static func split(fullName: String) -> (String?, String?) {
        guard !fullName.isEmpty else {
            return (nil, nil)
        }
        let components = fullName.components(separatedBy: .whitespacesAndNewlines)
        let lastName = components.last
        let firstName = components.dropLast().joined(separator: " ")
        return (firstName.isEmpty ? nil : firstName, lastName)
    }
}

Пройденные тестовые примеры:

func testThatItHandlesTwoComponents() {
    let (firstName, lastName) = NameComponentsSplitter.split(fullName: "John Smith")
    XCTAssertEqual(firstName, "John")
    XCTAssertEqual(lastName, "Smith")
}

func testThatItHandlesMoreThanTwoComponents() {
    var (firstName, lastName) = NameComponentsSplitter.split(fullName: "John Clark Smith")
    XCTAssertEqual(firstName, "John Clark")
    XCTAssertEqual(lastName, "Smith")

    (firstName, lastName) = NameComponentsSplitter.split(fullName: "John Clark Jr. Smith")
    XCTAssertEqual(firstName, "John Clark Jr.")
    XCTAssertEqual(lastName, "Smith")
}

func testThatItHandlesEmptyInput() {
    let (firstName, lastName) = NameComponentsSplitter.split(fullName: "")
    XCTAssertEqual(firstName, nil)
    XCTAssertEqual(lastName, nil)
}