it-roy-ru.com

Как добавить разделитель к строке в каждом N символов в Swift?

У меня есть строка, которая содержит двоичные цифры. Как разделить его на пары цифр?

Предположим, что строка:

let x = "11231245"

Я хочу добавить разделитель, такой как «:» (то есть двоеточие) после каждых 2 символов.

Я хотел бы вывод:

"11:23:12:45"

Как я мог сделать это в Swift?

14
Bolo

Swift 4.2 • Xcode 10

extension Collection {
    var pairs: [SubSequence] {
        var startIndex = self.startIndex
        let count = self.count
        let n = count/2 + (count % 2 == 0 ? 0 : 1)
        return (0..<n).map { _ in
            let endIndex = index(startIndex, offsetBy: 2, limitedBy: self.endIndex) ?? self.endIndex
            defer { startIndex = endIndex }
            return self[startIndex..<endIndex]
        }
    }
}

extension StringProtocol where Self: RangeReplaceableCollection {
    mutating func insert(separator: Self, every n: Int) {
        for index in indices.reversed() where index != startIndex &&
            distance(from: startIndex, to: index) % n == 0 {
            insert(contentsOf: separator, at: index)
        }
    }

    func inserting(separator: Self, every n: Int) -> Self {
        var string = self
        string.insert(separator: separator, every: n)
        return string
    }
}

Тестирование

let str = "112312451"

let final = str.pairs.joined(separator: ":")
print(final)      // "11:23:12:45:1"

let final2 = str.inserting(separator: ":", every: 2)
print(final2)      // "11:23:12:45:1\n"

var str2 = "112312451"
str2.insert(separator: ":", every: 2)
print(str2)   // "11:23:12:45:1\n"

var str3 = "112312451"
str3.insert(separator: ":", every: 3)
print(str3)   // "112:312:451\n"

var str4 = "112312451"
str4.insert(separator: ":", every: 4)
print(str4)   // "1123:1245:1\n"
42
Leo Dabus

Я пойду на это компактное решение (в Swift 4): 

let s = "11231245"
let r = String(s.enumerated().map { $0 > 0 && $0 % 2 == 0 ? [":", $1] : [$1]}.joined())

Вы можете сделать расширение и параметризовать шаг и разделитель, чтобы вы могли использовать его для каждого значения, которое вы хотите (в моем случае я использую его для вывода 32-битных шестнадцатеричных данных с пробелами):

extension String {
    func separate(every stride: Int = 4, with separator: Character = " ") -> String {
        return String(enumerated().map { $0 > 0 && $0 % stride == 0 ? [separator, $1] : [$1]}.joined())
    }
}

В вашем случае это дает следующие результаты:

let x = "11231245"
print (x.separate(every:2, with: ":")

$ 11:23:12:45
10
Stéphane de Luca
let y = String(
    x.characters.enumerate().map() {
        $0.index % 2 == 0 ? [$0.element] : [$0.element, ":"]
    }.flatten()
)
7
courteouselk

Коротко и просто, добавьте let или два, если хотите

extension String {

    func separate(every: Int, with separator: String) -> String {
        return String(stride(from: 0, to: Array(self).count, by: every).map {
            Array(Array(self)[$0..<min($0 + every, Array(self).count)])
        }.joined(separator: separator))
    }
}

let a = "separatemepleaseandthankyou".separate(every: 4, with: " ")

a is 

сепа оценить mepl легкость и спасибо вам

7
Joe Maher

Моя попытка в этом коде будет:

func insert(seperator: String, afterEveryXChars: Int, intoString: String) -> String {
    var output = ""
    intoString.characters.enumerate().forEach { index, c in
        if index % afterEveryXChars == 0 && index > 0 {
            output += seperator
        }
        output.append(c)
    }
    return output
}

insert(":", afterEveryXChars: 2, intoString: "11231245")

Какие выводы

11: 23: 12: 45

6
luk2302

Это мой код в Swift 4

let x = "11231245"

var newText = String()
    for (index, character) in x.enumerated() {
        if index != 0 && index % 2 == 0 {
            newText.append(":")
        }
        newText.append(String(character))
    }
    print(newText)

Результаты 11: 23: 12: 45

4
Evgeniy
extension String{

func separate(every: Int) -> [String] {
    return stride(from: 0, to: count, by: every).map {
        let ix0 = index(startIndex, offsetBy: $0);
        let ix1 = index(after:ix0);
        if ix1 < endIndex {
            return String(self[ix0...ix1]);
        }else{
            return String(self[ix0..<endIndex]);
        }
    }
}

/// или O(1) реализация (без подсчета)

func separate(every: Int) -> [String] {
    var parts:[String] = [];
    var ix1 = startIndex;
    while ix1 < endIndex {
        let ix0 = ix1;
        var n = 0;
        while ix1 < endIndex && n < every {
            ix1 = index(after: ix1);
            n += 1;
        }
        parts.append(String(self[ix0..<ix1]));
    }
    return parts;
}

"asdf234sdf".separate(every: 2).joined(separator: ":");
0
john07

Простое расширение String, которое не требует, чтобы исходная строка была кратна размеру шага (приращение):

extension String {
    func inserted(_ newElement: Character,atEach increment:Int)->String {
        var newStr = self

        for indx in stride(from: increment, to: newStr.count, by: increment).reversed() {
            let index = String.Index(encodedOffset: indx)
            newStr.insert(newElement, at: index)
        }

        return newStr
    }
 }
0
Steig