はじめに
再帰的な構造から特定プロパティの最大値や最小値を取得することは簡単に可能。
環境
- Swift 2.1.1
ポイント
-
子のコレクションに対し
reduce
を使い、必要な値以外は切り捨てる欲しい値(最大、最小等々)を抽出する。 - 単にそれを再帰的に繰り返していく。
- 子のコレクション(下記の例では
children
)がnil
の場合は気をつける。
最大値を取得するサンプルコード
import Darwin
class Foo<T where T: Comparable, T: Equatable> {
var value: T
var children: [Foo<T>]?
init(_ value: T) {
self.value = value
}
}
extension Foo {
var maximumValue: T {
return children?.reduce(value, combine: { max($0, $1.maximumValue) }) ?? value
}
}
// verification
var children = [Foo<UInt32>]()
var expected: UInt32 = 0
for _ in 0..<5 {
// child0
let value0 = arc4random_uniform(1000)
let subchild0 = Foo(value0)
expected = max(expected, value0)
// child1
let value1 = arc4random_uniform(1000)
let subchild1 = Foo(value1)
expected = max(expected, value1)
// child2
let value2 = arc4random_uniform(1000)
let subchild2 = Foo(value2)
expected = max(expected, value2)
// child3
let value3 = arc4random_uniform(1000)
let subchild3 = Foo(value3)
expected = max(expected, value3)
// child4
let value4 = arc4random_uniform(1000)
let subchild4 = Foo(value4)
expected = max(expected, value4)
// child
let value = arc4random_uniform(1000)
let child = Foo(value)
expected = max(expected, value)
child.children = [subchild0, subchild1, subchild2, subchild3, subchild4]
children += [child]
}
let value = arc4random_uniform(1000)
let foo = Foo(value)
foo.children = children
expected = max(expected, value)
print(expected == foo.maximumValue) // true