swift - 对数组进行分组以匹配另一个数组
问题描述
我有一组按月分组的日期。我正在尝试对另一个值数组进行分组,以使其与第一个数组匹配。那可能吗?
例如:
array1 = [[1,2,3],[4,5,6]]
array2 = ["one","two","three","four","five","six"]
我希望第二个数组与第一个数组分组相同,以便它们匹配:
array2 = [["one","two","three"],["four","five","six"]]
解决方案
一个想法的演变...
首先,二维数组的解决方案:
如果你知道你array1
是一个二维数组(元素数组的数组),你可以通过制作array2
一个迭代器并使用map
和compactMap
替换元素来做到这一点:
let array1 = [[1,2,3],[4,5,6]]
let array2 = ["one","two","three","four","five","six"]
var iter = array2.makeIterator()
let array3 = array1.map { arr in arr.compactMap { _ in iter.next() }}
print(array3)
结果:
[["one", "two", "three"], ["four", "five", "six"]]
更通用和通用的解决方案:
这是一个更通用的解决方案,它使用序列而不是array2
,这不取决于您提前知道array1
数组或序列的值的布局或类型:
func remap<S: Sequence>(_ array: [Any], using sequence: S) -> [Any] {
var iter = sequence.makeIterator()
func remap(_ array: [Any]) -> [Any] {
return array.compactMap { value in
if let subarray = value as? [Any] {
return remap(subarray)
} else {
return iter.next()
}
}
}
return remap(array)
}
这是如何工作的:
第二个数组或序列变成了一个称为迭代器的迭代器iter
,它允许我们通过重复调用来按顺序获取值iter.next()
。
然后使用第二个递归版本以深度优先遍历顺序remap()
转换[Any]
为[Any]
。compactMap()
用于替换数组的元素。在替换数组的元素时,如果该元素是另一个数组,它会递归调用remap()
该数组,直到它最终得到不是数组的值。如果元素是非数组元素,它将用迭代器中的next
值替换它,该迭代器按顺序提供序列(或第二个数组)的元素。我们使用compactMap
而不是来处理返回可选map
值的事实,因为在这种情况下它可能会用完返回的值。在这种情况下,iter.next()
nil
remap()
将用任何内容替换剩余的元素,同时仍保持第一个嵌套数组的结构。
例子:
// replace Ints with Strings
let array1: [Any] = [1, [2, 3], [4, [5, 6]]]
let array2 = ["one","two","three","four","five","six"]
let array3 = remap(array1, using: array2)
print(array3)
["one", ["two", "three"], ["four", ["five", "six"]]]
// replace Strings with Ints
let array4: [Any] = ["a", ["b", "c"], [[["d"]], "e"]]
let array5 = [1, 2, 3, 4, 5]
let array6 = remap(array4, using: array5)
print(array6)
[1, [2, 3], [[[4]], 5]]
// map letters to numbers starting with 5 using a partial range
print(remap(["a", ["b"], ["c", ["d"]]], using: 5...))
[5, [6], [7, [8]]]
// using stride to create a sequence of even numbers
let evens = stride(from: 2, to: Int.max, by: 2)
print(remap([["a", "b"], ["c"], [["d"]]], using: evens))
[[2, 4], [6], [[8]]]
// an example of not enough values in replacement array
print(remap([["a", "b"], ["c"], [["d"]]], using: [1]))
[[1], [], [[]]]
推荐阅读
- python - Rabbitmq 在 ioloop 保持活动状态时断开与消费者静默的连接
- html - 前端用户需要 Merchello 电子商务产品搜索功能方面的帮助
- html - HTML 门户 - 无法在“HTMLPortalElement”上执行“激活”门户元素与门户上下文无关
- javascript - JavaScript 中的并行编程
- c# - 列表
不在 C# 中反序列化 xml - java - 如何在 AWS S3 上的静态网页与 Java 中的 AWS Lambda 之间建立连接
- javascript - 如何从初始 JSON 输出中获取“p”的值
- java - 执行更新问题
- sql - 动态透视中的行总计
- react-native - 如何在子屏幕中隐藏底部选项卡导航器( TabBarVisible = true 不起作用)