将字符串拆分为数组数组[关闭]

问题描述 投票:-13回答:6

我正在使用Swift 4.2编写iOS应用程序

来自服务器的响应是一个字符串,其值由管道符“|”分隔。它包含许多行值。我想把它拆分成一个子数组。

响应示例:

“001 |苹果|红色| 002 |香蕉|黄色| 003 |葡萄|紫色”

对于此示例,输出应该是包含3个上述水果数组的数组。如果我使用response.componentsSeparatedByString("|")它会给我一个包含9个元素的数组,这是我不想要的。如果我考虑上面的例子,我需要的是一个包含3个元素的3个数组的数组。

预期产出:

[[001, "apple", "red"], [002, "banana", "yellow"], [003, "grapes", "purple"]]
ios swift
6个回答
4
投票

如果我得到了你想要收到的结果,那么这段代码可以满足你的需求:

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

let src = "001|apple|red|002|banana|yellow|003|grapes|purple"
let result = src.split(separator: "|").map(String.init).chunked(into: 3)
// result = [["001", "apple", "red"], ["002", "banana", "yellow"], ["003", "grapes", "purple"]]

如果您知道所得子阵列的预期大小,这将有效

你也可以从最后一行中删除.map(String.init),如果数组元素的类型为String.SubSequence就可以了


1
投票
  1. |字符拆分字符串
  2. 然后在结果数组的最后一个子数组中追加不是数字的元素
  3. 如果element为number,则将新子数组添加到结果数组中
  4. 重复2-3直到完成
let input = "001|apple|red|002|banana|yellow|003|grapes|purple"
let result: [[String]] = input
    .split(separator: "|")
    .reduce(into: []) { result, string in
        guard let _ = Int(string) else {
            result[result.count - 1].append(String(string))
            return
        }
        result.append([])
    }
/// result: [["apple", "red"], ["banana", "yellow"], ["grapes", "purple"]]

如果你想要持久化001,那么将result.append([])改为result.append([String(string)])

[["001", "apple", "red"], ["002", "banana", "yellow"], ["003", "grapes", "purple"]]

Important

此解决方案期望您的字符串将以数字开头或否则崩溃。 如果您不能保证您的字符串以数字开头,那么您需要在保护块中手动检查该数组是否为空。


1
投票

基本方式

let str = "001|apple|red|002|banana|yellow|003|grapes|purple"
let components = str.components(separatedBy: "|")
let chunkSize = 3
let loopCount = components.count/chunkSize

var packages: [Array<String>] = []
for index in  0..<loopCount {
    /// Starting index
    let numIndex = index * chunkSize

    /// Get the subarray of range
    let package = Array(components[numIndex..<(numIndex+chunkSize)])
    packages.append(package)
}

print(packages)

输出:

[[“001”,“apple”,“red”],[“002”,“banana”,“yellow”],[“003”,“grape”,“purple”]]


1
投票

有了正则表达式,你可以做这样的事情,感谢OOPer's extension

添加一个字符串扩展,根据正则表达式模式拆分字符串。

extension String {
    func split(usingRegex pattern: String) -> [String] {
        //### Crashes when you pass invalid `pattern`
        let regex = try! NSRegularExpression(pattern: pattern)
        let matches = regex.matches(in: self, range: NSRange(0..<utf16.count))
        let ranges = [startIndex..<startIndex] + matches.map{Range($0.range, in: self)!} + [endIndex..<endIndex]
        return (0...matches.count).map { String(self[ranges[$0].lowerBound..<ranges[$0+1].lowerBound]) }
    }
}

然后根据连续模式[0-9]{3} 3数字拆分字符串。

let str = "001|apple|red|002|banana|yellow|003|grapes|purple|004|this|is|a|test|one|005|so|is|this"
let pattern = "[0-9]{3}"
let result = str.split(usingRegex: pattern)

var all:[[String]] = []
for row in result {
    let split = row.split(separator: "|").map({ (substring) in
        return String(substring)
    })
    if split.count != 0 {
        all.append(split)
    }
}

dump(all)

我在操场上测试了这个并得到了以下结果:

▿ 5 elements
  ▿ 3 elements
    - "001"
    - "apple"
    - "red"
  ▿ 3 elements
    - "002"
    - "banana"
    - "yellow"
  ▿ 3 elements
    - "003"
    - "grapes"
    - "purple"
  ▿ 6 elements
    - "004"
    - "this"
    - "is"
    - "a"
    - "test"
    - "one"
  ▿ 4 elements
    - "005"
    - "so"
    - "is"
    - "this"

如果您决定要从结果数组中排除ID,则可以修改扩展名返回到以下内容:

return (0...matches.count).map { String(self[ranges[$0].upperBound..<ranges[$0+1].lowerBound]) }

这将切换返回范围以使用upperBound而不是lowerBound


0
投票

您可以使用byWords选项在范围内使用String方法enumerateSubstrings,检查字符串是否为整数,如果是,则将带有该字符串的新数组附加到结果,否则将该字附加到最后的结果数组:

let string = "001|apple|red|002|banana|yellow|003|grapes|purple"
var result: [[Substring]] = []
string.enumerateSubstrings(in: string.startIndex..., options: .byWords) { _, range, _, _ in
    let word = string[range]
    if let _ = Int(word) {
        result.append([word])
        // or just a new empty array
        // result.append([])
    } else {
        result[result.index(before: result.endIndex)].append(word)
    }
}

print(result)   // "[["001", "apple", "red"], ["002", "banana", "yellow"], ["003", "grapes", "purple"]]\n"

0
投票

好的你可以递归地做

let input = "001|apple|red|002|banana|yellow|003|grapes|purple"

let array = input.components(separatedBy: "|")


// Get Chunks from array
 extension Array {
      func getFirstElements(upTo position: Int) -> Array<Element> {
         let arraySlice = self[0 ..< position]
         return Array(arraySlice)
      }
  }

func recersivelyGetArray (array:[String], slice:inout [[String]]) {

  guard !array.isEmpty else{
    return
  }

  var copyArray = array

  var chunkSize = 3
  if  array.count >= 3 {
    chunkSize = 3
  } else {
    chunkSize = array.count
  }
  let threeElements =  copyArray.getFirstElements(upTo: chunkSize)
  slice.append(threeElements)

  copyArray.removeFirst(chunkSize)

  recersivelyGetArray(array: copyArray, slice: &slice)


}

var inoutResult = [[String]]()

recersivelyGetArray(array: array, slice: &inoutResult)

print(inoutResult) 

产量

案例1输入

let input = "001|apple|red|002|banana|yellow|003|grapes|purple"

[[“001”,“apple”,“red”],[“002”,“banana”,“yellow”],[“003”,“grape”,“purple”]]

案例2输入

let input = "001|apple|red|002|banana|yellow|003|grapes"

[[“001”,“apple”,“red”],[“002”,“banana”,“yellow”],[“003”,“grape”]]

© www.soinside.com 2019 - 2024. All rights reserved.