Swift: разбить строку на массив



Допустим, у меня есть строка:



var fullName: String = "First Last"


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



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

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


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

833   30  

30 ответов:

Быстрый способ-использовать глобальную функцию 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 

Просто вызовите 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]

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

Для Свифта 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]

Для Свифта 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.0 (май 24, 2017)

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

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"]

В качестве альтернативы ответу 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"]

Swift 4

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

Xcode 9 Swift 4 или Xcode 8.2.1 * Swift 3.0.2

Если вам просто нужно правильно отформатировать имя человека, вы можете использовать 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 convufgured 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."
}

Введите описание изображения здесь

Проблема пробелов

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

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

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

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

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

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

NSCharacterSet пробелы

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

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

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

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

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

Swift 3

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

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

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

Метод 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("")

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

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

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

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

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

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

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

Свифт 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"]

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

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

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 здесьдля получения дополнительной информации.

Надеюсь, что это полезно

Swift 4: разбить строку на массив. Шаг 1: назначить строку. Шаг 2: на основе @ spliting. Примечание: переменное имя.компоненты (separatedBy: "ключевое слово 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)

В Swift 4.1 и Xcode 9.4.1

//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 result is Array.
//Direct 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

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

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(separator: " "))
print(line.split(separator: " ", maxSplits: 1))//This can split your string into 2 parts
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.
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))
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]

Xcode 7.2 (7C68)

Swift 2.2 обработка ошибок & capitalizedString добавлено:

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
}

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

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

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

Старый:

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

Новое:

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

Примечания К Выпуску Apple

Для swift 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]

Согласно Swift 2.2

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

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

Наслаждайтесь. :)

Вот алгоритм, который я только что построил, который разделит 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", "--"]

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

Свифт 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)

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

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

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

Вывод:

["First", ""]

Я не нашел решения, которое бы обрабатывало имена с 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)
}
var fullName = "James Keagan Michael"
let first = fullName.components(separatedBy: " ").first?.isEmpty == false ? fullName.components(separatedBy: " ").first! : "John"
let last =  fullName.components(separatedBy: " ").last?.isEmpty == false && fullName.components(separatedBy: " ").last != fullName.components(separatedBy: " ").first ? fullName.components(separatedBy: " ").last! : "Doe"
  • запретить одинаковые имя и фамилию
  • Если полное имя недопустимо, замените его значением "John Doe"

Comments

    Ничего не найдено.