web-dev-qa-db-fra.com

Fractionner une chaîne en un tableau dans Swift?

Dis que j'ai une ficelle ici:

var fullName: String = "First Last"

Je veux diviser la base de chaîne sur un espace et assigner les valeurs à leurs variables respectives

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

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

De plus, les utilisateurs peuvent parfois ne pas avoir de nom de famille.

632
blee908

La méthode Swift consiste à utiliser la fonction globale split, comme suit:

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

avec Swift 2

Dans Swift 2, l'utilisation de la division devient un peu plus compliquée en raison de l'introduction du type interne CharacterView. Cela signifie que String n'adopte plus les protocoles SequenceType ou CollectionType et que vous devez utiliser la propriété .characters pour accéder à une représentation de type CharacterView d'une instance String. (Remarque: CharacterView adopte les protocoles SequenceType et 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 
754
Ethan

Appelez simplement la méthode componentsSeparatedByString sur votre fullName

import Foundation

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

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

Mise à jour pour Swift 3 +

import Foundation

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

let name    = fullNameArr[0]
let surname = fullNameArr[1]
960
Chen-Tsu Lin

La méthode la plus simple consiste à utiliser componentsSeparatedBy:

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

Pour 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]
170
Wyetro

Swift Dev. 4.0 (24 mai 2017)

Une nouvelle fonction split dans Swift 4 (Beta).

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

Sortie:

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

Accéder aux valeurs:

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

Xcode 8.1/Swift 3.0.1

Voici la façon dont plusieurs délimiteurs avec tableau.

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

Sortie:

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

En guise d'alternative à la réponse de WMios, vous pouvez également utiliser componentsSeparatedByCharactersInSet, ce qui peut être pratique si vous avez plusieurs séparateurs (espaces, virgules, etc.).

Avec votre contribution spécifique:

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

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

Utiliser plusieurs séparateurs:

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

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

Swift 4 ou ultérieur

Si vous avez juste besoin de formater correctement un nom de personne, vous pouvez utiliser PersonNameComponentsFormatter .

La classe PersonNameComponentsFormatter fournit des représentations localisées des composants du nom d’une personne, représentées par un objet PersonNameComponents. Utilisez cette classe pour créer des noms localisés lors de l'affichage des informations de nom de personne à l'utilisateur.


// 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

éditer/mettre à jour:

Swift 5 ou ultérieur

Pour diviser simplement une chaîne en caractères non-lettres, nous pouvons utiliser la nouvelle propriété Character isLetter :

let fullName = "First Last"

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

Swift 4

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

La question des espaces

Généralement, les gens réinventent ce problème et les mauvaises solutions à plusieurs reprises. Est-ce un espace? "" et que dire de "\ n", "\ t" ou de caractères unicodes que vous n’avez jamais vus, en grande partie parce qu’ils sont invisibles. Alors que vous pouvez vous en sortir

Une solution faible

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

Si vous avez besoin de secouer la réalité, regardez une vidéo de la WWDC sur des chaînes ou des dates. En bref, il est presque toujours préférable de permettre à Apple de résoudre ce type de tâche banale.

Solution robuste: utilisez NSCharacterSet

La meilleure façon de le faire correctement, à mon humble avis, consiste à utiliser NSCharacterSet puisque, comme indiqué précédemment, votre espace peut ne pas correspondre à vos attentes et que Apple a fourni un jeu de caractères. Pour explorer les différents jeux de caractères fournis, consultez le documentation du développeur NSCharacterSet d'Apple, puis augmentez ou créez un nouveau jeu de caractères s'il ne correspond pas à vos besoins.

NSCharacterSet espaces blancs

Renvoie un jeu de caractères contenant les caractères des catégories Unicode General Zs et 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)
31

Dans Swift 4.2 et Xcode 10

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

Option 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!)

Option 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)

Option 3

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

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

Par Apple Documentation ....

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))
26
iOS

Swift 4 facilite beaucoup le fractionnement des caractères, utilisez simplement la nouvelle fonction de fractionnement pour Strings.

Exemple: let s = "hi, hello" let a = s.split(separator: ",") print(a)

Maintenant, vous avez un tableau avec 'salut' et 'bonjour'.

21
Jeroen Zonneveld

Swift

let line = "AAA    BBB\t CCC"
let fields = line.components(separatedBy: .whitespaces).filter {!$0.isEmpty}
  • Renvoie trois chaînes AAA, BBB et CCC
  • Filtre les champs vides
  • Gère plusieurs espaces et caractères de tabulation
  • Si vous voulez gérer de nouvelles lignes, remplacez .whitespaces par .whitespacesAndNewlines
16
tepl

Xcode 8.0/Swift

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

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

Long chemin:

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
NikaE

Swift 4, Xcode 10 et iOS 12 Update 100% de travail

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

Voir le documentation Apple ici pour plus d'informations.

11
Xcodian Solangi

J'ai eu un scénario où plusieurs caractères de contrôle peuvent être présents dans la chaîne que je veux diviser. Plutôt que de conserver un tableau de ceux-ci, je laisse simplement Apple gérer cette partie.

Ce qui suit fonctionne avec Swift 3.0.1 sur iOS 10:

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

J'ai trouvé un cas intéressant, que

méthode 1

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

Lorsque j'ai utilisé cette commande pour scinder un symbole à partir des données chargées depuis le serveur, il peut être scindé pendant le test dans le simulateur et synchronisé avec le périphérique de test, mais pas dans l'application de publication, ni ad hoc.

Il me faut beaucoup de temps pour suivre cette erreur, cela pourrait être maudit à partir de certaines Swift Version, ou de certaines versions d'iOS ou des deux.

Il ne s'agit pas non plus du code HTML, puisque j'essaie de stringByRemovingPercentEncoding et que cela ne fonctionne toujours pas.

ajout 10/10/2015

dans Swift 2.0, cette méthode a été remplacée par

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

méthode 2

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

Lorsque j'ai utilisé cette commande, il peut fractionner les mêmes données que celles chargées depuis le serveur correctement


Conclusion, je suggère vraiment d'utiliser la méthode 2

string.componentsSeparatedByString("")
8
Sruit A.Suk

Mise à jour pour Swift 5 et de manière simple

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: [",", " ", "!",".","?"])

Cela imprime,

["Bob", "hit", "a", "balle", "", "le", "hit", "balle", "vola", "loin", "après", "après", "était" "," hit "," "," Bonjour "," "," Hie "," "," Comment "," r "," u "," "]

Cependant, si vous voulez filtrer la chaîne vide,

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

Sortie,

["Bob", "hit", "a", "balle", "le", "hit", "balle", "vola", "loin", "après", "il", "était", " hit "," bonjour "," hie "," comment "," r "," u "]

Mais assurez-vous que Foundation est importé

7
Mithra Singam

La plupart de ces réponses supposent que l'entrée contient un espace - pas blanc, et un seul espace. Si vous pouvez faire cette hypothèse en toute sécurité, la réponse acceptée (de bennett) est assez élégante et constitue également la méthode que je choisirai lorsque je le pourrai.

Lorsque nous ne pouvons pas formuler cette hypothèse, une solution plus robuste doit couvrir les tâches suivantes que la plupart des réponses ne prennent pas en compte ici:

  • onglets/nouvelles lignes/espaces (espaces), y compris récurrents caractères
  • espaces de début et de fin
  • Apple/Linux (\n) et Windows (\r\n) caractères de nouvelle ligne

Pour couvrir ces cas, cette solution utilise regex pour convertir tous les espaces (y compris les caractères récurrents et les caractères de nouvelle ligne de Windows) en un seul espace, les rogner, puis les diviser en un seul espace:

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

Ou sans fermetures, vous pouvez le faire en Swift 2:

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

Étapes pour diviser une chaîne en un tableau dans Swift 4.

  1. assigner une chaîne
  2. basé sur @ splitting.

Remarque: variableName.components (séparés par: "mot clé divisé")

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

let string = "loremipsum.dolorsant.amet:"

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

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

sortie

loremipsum
dolorsant
amet:
total: 3
4
MrMins

Supposons que vous ayez une variable nommée "Hello World" et que vous puissiez l'utiliser comme suit si vous souhaitez la scinder et la stocker dans deux variables différentes.

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

Swift 2.2Traitement des erreurs et chaîne de caractères majuscule ajoutée:

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
}
2
Aqib Mumtaz
let str = "one two"
let strSplit = str.characters.split(" ").map(String.init) // returns ["one", "two"]

Xcode 7.2 (7C68)

2
Amr Lotfy

Je cherchais une séparation souple, telle que explode de PHP où des séquences vides sont incluses dans le tableau résultant, cela a fonctionné pour moi:

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

Sortie:

["First", ""]
2
AamirR

La manipulation des chaînes est toujours un défi dans Swift et elle change constamment, comme vous pouvez le constater à partir d'autres réponses. Espérons que les choses se stabilisent et que cela devienne plus simple. C'est le moyen de le faire avec la version 3.0 actuelle de Swift avec plusieurs caractères de séparation.

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)
2
possen

Pour 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]
1
abinop

Voici un algorithme que je viens de construire, qui divisera une String par un quelconque Character du tableau et si vous souhaitez conserver les sous-chaînes avec des caractères séparés, définissez le paramètre 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
            }
        }
    }
}

Exemple:

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

Swift 5 et plus

let fullString = "Last First Middle"
let fullNameArr = fullString.components(separatedBy: " ")
1
midhun p

Cela a de nouveau changé dans la bêta 5. Weee! C'est maintenant une méthode sur CollectionType

Vieux:

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

Nouveau:

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

Notes de publication d'Apple

1
Daniel H.

Je n'ai pas trouvé de solution capable de gérer les noms avec 3 composants ou plus et de prendre en charge les anciennes versions 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)
    }
}

Cas de test réussis:

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)
}
0
Vadim Bulavin

selon Swift 2.2

Vous venez d'écrire 2 code de ligne et vous obtiendrez la chaîne divisée.

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

Prendre plaisir. :)

0
Gautam Sareriya
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"
  • Refuser les mêmes prénom et nom
  • Si un nom complet n'est pas valide, prenez la valeur de marque de réservation "John Doe".
0
jnblanchard