如何按给定大小的块从字符串拆分为数组
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"]
我想按给定大小的块拆分字符串 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"]