Swift:如何将指定数组元素按规则分组为目标二维数组?
如何在Swift中实现指定的数组分组需求?
看起来你需要按Banana→Apple→Orange的固定序列循环分组原数组,直到元素耗尽,最后剩下的不完整序列也保留下来对吧?我给你两种实用的实现方式,都能完美达成你的需求:
方法一:直观的状态跟踪写法
这种写法逻辑清晰,容易理解,完全贴合你的分组规则:
let originalArray = ["Banana", "Apple", "Banana", "Orange", "Apple", "Banana", "Orange", "Apple"] // 定义我们要匹配的分组模板 let groupPattern = ["Banana", "Apple", "Orange"] var resultGroups: [[String]] = [] var currentGroup: [String] = [] var patternIndex = 0 for item in originalArray { // 如果当前元素正好是我们要找的下一个模板元素 if item == groupPattern[patternIndex] { currentGroup.append(item) patternIndex += 1 // 凑齐一组完整的模板序列了,就加入结果列表,重置当前分组和索引 if patternIndex == groupPattern.count { resultGroups.append(currentGroup) currentGroup = [] patternIndex = 0 } } } // 把最后没凑齐的分组也加进去(如果有的话) if !currentGroup.isEmpty { resultGroups.append(currentGroup) } print(resultGroups) // 输出:[["Banana", "Apple", "Orange"], ["Banana", "Apple", "Orange"], ["Banana", "Apple"]]
这个方法会严格按照Banana→Apple→Orange的顺序去原数组里找匹配的元素,凑齐一组就封包,继续找下一组,完美匹配你给出的目标结果。
方法二:函数式风格的Reduce写法
如果你偏好Swift的函数式编程,可以用reduce来实现,逻辑和上面完全一致,但代码更紧凑:
let originalArray = ["Banana", "Apple", "Banana", "Orange", "Apple", "Banana", "Orange", "Apple"] let groupPattern = ["Banana", "Apple", "Orange"] // 用reduce跟踪分组状态:已完成的分组、当前正在收集的分组、模板匹配索引 let intermediateResult = originalArray.reduce(into: (completedGroups: [[String]](), current: [String](), patternPos: 0)) { state, item in guard item == groupPattern[state.patternPos] else { return } state.current.append(item) state.patternPos += 1 if state.patternPos == groupPattern.count { state.completedGroups.append(state.current) state.current = [] state.patternPos = 0 } } // 组装最终结果 var finalResult = intermediateResult.completedGroups if !intermediateResult.current.isEmpty { finalResult.append(intermediateResult.current) } print(finalResult) // 输出和上面完全一致
补充说明
这两种方法的核心逻辑都是跟踪当前需要匹配的模板元素,找到一个就加入当前分组,直到凑齐完整的模板序列,然后重置状态继续循环。如果原数组里有不符合模板顺序的元素,会直接被忽略(不过看你的示例数组是完全符合模板循环逻辑的,所以不用担心这个问题)。
内容的提问来源于stack exchange,提问作者Dr.Dean
相关产品推荐
相关产品推荐

