如何按给定大小的块从字符串拆分为数组

How can split from string to array by chunks of given size

我想按给定大小的块拆分字符串 2

示例:

字符串 "1234567" 并且输出应该是 ["12", "34", "56","7"]

var testString = "abcdefghijklmnopqrstu"
var startingPoint: Int = 0
var substringLength: Int = 1
var substringArray = [AnyHashable]()
for i in 0..<(testString.count ?? 0) / substringLength {
    var substring: String = (testString as NSString).substring(with: NSRange(location: startingPoint, length: substringLength))
    substringArray.append(substring)
    startingPoint += substringLength
}
print("\(substringArray)")

输出: ( 一种, 乙, C, 丁, 电子, F, G, H, 一世, j, , 我, 米, , 哦, , 问, , 秒, 吨, 你 )

您可以按照以下每 n 个元素对集合元素(在本例中为字符)进行分组:

extension Collection {
    func unfoldSubSequences(limitedTo maxLength: Int) -> UnfoldSequence<SubSequence,Index> {
        sequence(state: startIndex) { start in
            guard start < self.endIndex else { return nil }
            let end = self.index(start, offsetBy: maxLength, limitedBy: self.endIndex) ?? self.endIndex
            defer { start = end }
            return self[start..<end]
        }
    }
    func subSequences(of n: Int) -> [SubSequence] {
        .init(unfoldSubSequences(limitedTo: n))
    }
}

let numbers = "1234567"
let subSequences = numbers.subSequences(of: 2)
print(subSequences)    // ["12", "34", "56", "7"]

edit/update:

如果您想将超出的字符追加到最后一组:

extension Collection {
    func unfoldSubSequencesWithTail(lenght: Int) -> UnfoldSequence<SubSequence,Index> {
        let n = count / lenght
        var counter = 0
        return sequence(state: startIndex) { start in
            guard start < endIndex else { return nil }
            let end = index(start, offsetBy: lenght, limitedBy: endIndex) ?? endIndex
            counter += 1
            if counter == n {
                defer { start = endIndex }
                return self[start...]
            } else {
                defer { start = end }
                return self[start..<end]
            }
        }
    }
    func subSequencesWithTail(n: Int) -> [SubSequence] {
        .init(unfoldSubSequencesWithTail(lenght: n))
    }
}

let numbers = "1234567"
let subSequencesWithTail = numbers.subSequencesWithTail(n: 2)
print(subSequencesWithTail)    // ["12", "34", "567"]
extension String {
    func split(len: Int) -> [String] {
        var currentIndex = 0
        var array = [String]()
        let length = self.characters.count
        while currentIndex < length {
            let startIndex = self.startIndex.advancedBy(currentIndex)
            let endIndex = startIndex.advancedBy(len, limit: self.endIndex)
            let substr = self.substringWithRange(Range(start: startIndex, end: endIndex))
            array.append(substr)
            currentIndex += len
        }
        return array
    }
}

"123456789".split(2)

//output: ["12", "34", "56", "78", "9"]

试试这个

func SplitString(stringToBeSplitted:String, By:Int) -> [String]
    {
        var newArray = [String]()
        var newStr = String()
        for char in stringToBeSplitted
        {
            newStr += String(char)
            if newStr.count == By
            {
                newArray.append(newStr)
                newStr = ""
            }

        }
        return newArray
    }

我在objective c中写了一个方法如下,

-(NSMutableArray*)splitString : (NSString*)str withRange : (int)range{


NSMutableArray *arr = [[NSMutableArray alloc]init];

NSMutableString *mutableStr = [[NSMutableString alloc]initWithString:str];

int j = 0;
int counter = 0;

for (int i = 0; i < str.length; i++) {

    j++;

    if (range == j) {

        j = 0;


        if (!(i == str.length - 1)) {

             [mutableStr insertString:@"$" atIndex:i+1+counter];
        }



        counter++;
    }
}



arr = (NSMutableArray*)[mutableStr componentsSeparatedByString:@"$"];

NSLog(@"%@",arr);

return arr;
}

你可以这样调用这个方法,

 [self splitString:@"123456" withRange:2];

结果将是,

(
12,
34,
56
)

您也可以试试下面的代码:

var arrStr: [Substring] = []
    let str = "1234567"
    var i = 0
    while i < str.count - 1 {
        let index = str.index(str.startIndex, offsetBy: i)
        //Below line gets current index and advances by 2
        let substring = str[index..<str.index(index, offsetBy: 2)]
        arrStr.append(substring)
        i += 2
    }
    if str.count % 2 == 1 {
        arrStr.append(str.suffix(1))
    }
    print(arrStr)

有个笨办法,你可以想想数据模型的规则

    var strOld = "123456"
    print("The original string:\(strOld)")

    strOld.insert("、", at: strOld.index(before: strOld.index(strOld.startIndex, offsetBy: 3)))

    strOld.insert("、", at: strOld.index(before: strOld.index(strOld.startIndex, offsetBy: 6)))

    print("After inserting:\(strOld)")

    let str = strOld

    let splitedArray = str.components(separatedBy: "、")
    print("After the split of the array:\(splitedArray)")

    let splitedArrayOther = str.split{[=10=] == "、"}.map(String.init)
    print("After break up the array (method 2):\(splitedArrayOther)")

结果:

The original string:123456
After inserting:12、34、56
After the split of the array:["12", "34", "56"]
After break up the array (method 2):["12", "34", "56"]

这是一个简短(干净)的解决方案,感谢递归:

extension Collection {
    func chunks(ofSize size: Int) -> [SubSequence] {
        // replace this by `guard count >= size else { return [] }`
        // if you want to omit incomplete chunks
        guard !isEmpty else { return [] }
        return [prefix(size)] + dropFirst(size).chunks(ofSize: size)
    }
}

递归应该不会造成性能问题,因为 Swift 支持尾调用优化。

此外,如果 Swift 数组在添加或附加元素时真的很快(就像 Objective-C 那样),那么数组操作应该很快。

因此您将获得既快速又可读的代码(假设我的数组假设是正确的)。

Swift 5

extension Array {
    func chunks(size: Int) -> [[Element]] {
        return stride(from: 0, to: count, by: size).map {
            Array(self[[=10=] ..< Swift.min([=10=] + size, count)])
        }
    }
}

extension String {
    func chunks(size: Int) -> [String] {
        map { [=10=] }.chunks(size: size).compactMap { String([=10=]) }
    }
}

let s = "1234567"
print(s.chunks(size: 2)) // ["12", "34", "56", "7"]