Подтвердить что ты не робот

Быстрая версия компонентовSeparatedByString

Я знаю его вопрос noob, я действительно ищу вокруг, прежде чем спросить. Но нет точного ответа на то, что я хочу знать. Как мы разделяем строку в массив без использования Objective C? Например:

var str = "Today is so hot"
var arr = str.componentsSeparatedByString(" ")  // *
  • Я знаю, что это не работает, но я так ищу. Я хочу разбить строку на "" (или другую char/string)

Идея: Это может быть очень хорошо для меня, делая расширение класса string. Но я не знаю, как это сделать.

Изменить: Забыть import Foundation. Если я импортирую фундамент, он будет работать. Но есть ли способ расширить класс String? Спасибо вам

4b9b3361

Ответ 1

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

let str = "Today is so hot"
let arr = split(str, { $0 == " "}, maxSplit: Int.max, allowEmptySlices: false)
println(arr) // [Today, is, so, hot]

Обновление для Swift 1.2: Порядок изменения параметров с помощью Swift 1.2 (Xcode 6.3), сравните split теперь жалуется на отсутствие "isSeparator "" :

let str = "Today is so hot"
let arr = split(str, maxSplit: Int.max, allowEmptySlices: false, isSeparator: { $0 == " "} )
println(arr) // [Today, is, so, hot]

Обновление для Swift 2: См. Ответ Стюарта.

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

let str = "Today is so hot"
let arr = str.characters.split(separator: " ").map(String.init)
print(arr)

Ответ 2

В Swift 2 синтаксис для этого стал более кратким. Функция split верхнего уровня теперь представляет собой метод на CollectionType (который соответствует String.CharacterView).

Существует две версии метода: первая принимает замыкание как предикат, чтобы указать, следует ли рассматривать данный элемент как разделитель, а другой просто берет элемент для указания в качестве разделителя - это, скорее всего, то, что вы хотите на 99% разрывов строк. У них обоих есть пара дефолтных параметров (подробности см. В документах), что помогает сохранить хороший вызов метода.

Стоит отметить, что split(_:) возвращает SubSequence (в основном a Slice), поэтому в большинстве случаев требуется преобразовать обратно в массив String, который обычно более полезен.

let str = "Today is so hot"
let words = str.characters.split(" ").map { String($0) }  // or `.map(String.init)`

Объяснение выражения строкового инициализатора (map(String.init))

map - это метод, который принимает функцию как аргумент. В большинстве случаев вы, вероятно, просто используете закрывающее закрытие (неназванная функция) в качестве аргумента map, например:

func createString(from character: Character) -> String {
    // ...
}

let strings = characters.map { createString(from: $0) }

Но следующее более кратким и справедливым:

let strings = characters.map(createString(from:))
// or even:
let strings = characters.map(createString) // argument names inferred from context.

В приведенном выше примере createString(from:) и createString являются функциональными выражениями. map ожидает функцию как аргумент, и в качестве аргумента можно передать выражение функции. Вы можете передать выражение функции в любом месте, которое принимает функцию как аргумент, поэтому вы можете использовать sort как это для типов, соответствующих Comparable:

let sortedStrings = strings.sorted(by: <)

// `<` is just a function expression for a function that is essentially declared something like this:
func <(lhs: String, rhs: String) -> Bool {
    // ...
}

String.init является выражением инициализатора. Его можно использовать точно так же, как выражение функции - он сам описывает функцию, которая принимает один Character в качестве аргумента и возвращает значение типа String (хотя String.init перегружен и может быть прошло много разных аргументов).

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

// - Closure expression syntax used.
// - Explicit argument names & types.
// - Long-hand string initialization.
let strings = characters.map({ (character: CharacterView) -> String in
    return String.init(character)
})

// - Trailing closure syntax used (parentheses omitted).
// - Closure argument and return types inferred from context (type names omitted).
// - Short-hand (standard, really) string initialization.
let strings = characters.map { character in
    return String(character)
}

// - Implicit return since using single expression in the closure (`return` keyword omitted).
let strings = characters.map { character in String(character) }

// - Shorthand argument names (`in` keyword and argument names omitted).
let strings = characters.map { String($0) }

// - Initializer expression syntax used (curly braces omitted, argument implicitly passed to the initializer).
let strings = characters.map(String.init(_:))

// - Initializer expression argument names inferred from context. 
let strings = characters.map(String.init)

Ответ 3

В Swift 3.0  Используйте components(separatedBy:) для строки, чем componentsSeparatedByString.

Пример кода обмена

let tempString = "1.Wash your hands\n2.Check you phone\n3.Click home button".components(separatedBy: "\n")
print(tempString)

Ответ 4

"Я знаю, что он не работает"

Хорошо, для меня это так. В Swift REPL:

  1> import Foundation
  2> "a b c".componentsSeparatedByString(" ")
$R6: String[] = size=3 {
  [0] = {
    core = {
      _baseAddress = Builtin.RawPointer = 0x0000000100407980
      _countAndFlags = -4611686018427387903
      _owner = Some {
        Some = @"a"
      }
    }
  }
  [1] = {
    core = {
      _baseAddress = Builtin.RawPointer = 0x0000000100408e50 -> 0x00007fff7cde0062 (void *)0x001b00007fff7cdd
      _countAndFlags = -4611686018427387903
      _owner = Some {
        Some = @"b"
      }
    }
  }
  [2] = {
    core = {
      _baseAddress = Builtin.RawPointer = 0x0000000100408dd0
      _countAndFlags = -4611686018427387903
      _owner = Some {
        Some = @"c"
      }
    }
  }
}