我使用这个 Stack Overflow 问题,有以下代码。
let numbers = [1,[2,3]] as [Any]
var flattened = numbers.flatMap { $0 }
print(flattened) // [1, [2, 3]]
我希望将flattened
设置为[1, 2, 3]
,而不是[1, [2, 3]]
。
在Swift中,最简单/最清晰的方法是什么?
extension Collection where Element == Any {
var joined: [Any] { flatMap { ($0 as? [Any])?.joined ?? [$0] } }
func flatMapped<T>(_ type: T.Type? = nil) -> [T] { joined.compactMap { $0 as? T } }
}
let objects: [Any] = [1,[2,3],"a",["b",["c","d"]]]
let joined = objects.joined() // [1, 2, 3, "a", "b", "c", "d"]
let integers = objects.flatMapped(Int.self) // [1, 2, 3]
// setting the type explicitly
let integers2: [Int] = objects.flatMapped() // [1, 2, 3]
// or casting
let strings = objects.flatMapped() as [String] // ["a", "b", "c", "d"]
lazy
都是多余的,因为您正在使用返回数组的重载(即急切评估)。您可以将 ($0 is T ? [$0 as! T] : [])
改写为 ($0 as? T).map { [$0] } ?? []
,不过个人而言,我可能会使用 switch
(例如 https://gist.github.com/hamishknight/eca9b0be62056284ec37c3d49dd7db65)。另外,就我个人而言,我会将 flattened
设为方法,因为它不是 O(1);但我知道您喜欢计算属性 :) - Hamish解决这个问题可能有更好的方法,但一个解决方案是编写自己的Array扩展程序:
extension Array {
func anyFlatten() -> [Any] {
var res = [Any]()
for val in self {
if let arr = val as? [Any] {
res.append(contentsOf: arr.anyFlatten())
} else {
res.append(val)
}
}
return res
}
}
let numbers = [1,[2, [4, 5] ,3], "Hi"] as [Any]
print(numbers.anyFlatten())
输出:
[1, 2, 4, 5, 3, "Hi"]
该解决方案可处理任何嵌套的数组。
self.flatMap{ ($0 as? [Any]).map{ $0.anyFlatten() } ?? [$0] }
- Alexanderreturn
语句出现在每次递归调用的末尾。你的 return
语句被调用的次数等于所有子数组深度的总和。在我的代码中,return
的效果相当于你的代码中的 .append(contentsOf:)
和 append(_:)
调用。对于我来说,将数组 Array(0..<10)
(10个元素,深度均为 1)展开将会调用 return
10 次(10个元素),而对于你来说只会调用一次(最大深度为1),但这个计数完全测量了不同的东西。 - Alexanderextension Array {
func anyFlatten() -> [Any] {
return self.flatMap{ ($0 as? [Any]).map{ $0.anyFlatten() } ?? [$0] }
}
}
extension Array {
func anyFlatten() -> [Any] {
return self.flatMap{ element -> [Any] in
if let elementAsArray = element as? [Any] { return elementAsArray.anyFlatten() }
else { return [element] }
}
}
}
flatMap
适用于一个数组的数组,而不是Any
数组。 - rmaddyflatMap
的方法可以帮助我达到我想要的效果? - Charlie Fish