既知の要素型への (試行された) 型変換に基づいて、単純な要素ごとの比較関数を構築する
(オプションの)要素の配列を比較することを目的としているため、ブロックを使用して配列の要素を「サードパーティのさまざまな既知の型にAnyダウンキャストする」ことにより、要素ごとの比較を実行する関数を構築できます。配列」 . 特定の型に対応する要素の位置を指定する必要はなく (これは配列の異なるセット間で異なる可能性があるため)、特定の要素の可能性があるさまざまな型の完全なセットのみを指定する必要があることに注意してください。switch
このような関数の例を以下に示します。
func compareAnyArrays(arr1: [Any?], _ arr2: [Any?]) -> Bool {
/* element-by-element downcasting (to known types) followed by comparison */
return arr1.count == arr2.count && !zip(arr1, arr2).contains {
/* note that a 'true' below indicates the arrays differ (i.e., 'false' w.r.t. array equality) */
if let v1 = $1 {
/* type check for known types */
switch $0 {
case .None: return true
case let v0 as String:
if let v1 = v1 as? String { return !(v0 == v1) }; return true
case let v0 as Int:
if let v1 = v1 as? Int { return !(v0 == v1) }; return true
/* ...
expand with the known possible types of your array elements
... */
case _ : return true
/* */
}
}
else if let _ = $0 { return true }
return false
}
}
または、別の方法として、@Roman Sausarnes:s answerswitchのヘルパー関数を (わずかに変更して) 使用することで、ブロックの肥大化を少し減らします。compare(...)
func compareAnyArrays(arr1: [Any?], _ arr2: [Any?]) -> Bool {
/* modified helper function from @Roman Sausarnes:s answer */
func compare<T: Equatable>(obj1: T, _ obj2: Any) -> Bool {
return obj1 == obj2 as? T
}
/* element-by-element downcasting (to known types) followed by comparison */
return arr1.count == arr2.count && !zip(arr1, arr2).contains {
/* note also that a 'true' below indicates the arrays differ
(=> false w.r.t. equality) */
if let v1 = $1 {
/* type check for known types */
switch $0 {
case .None: return true
case let v0 as String: return !compare(v0, v1)
case let v0 as Int: return !compare(v0, v1)
/* ...
expand with the known possible types of your array elements
... */
case _ : return true
/* */
}
}
else if let _ = $0 { return true }
return false
}
}
使用例:
/* Example usage #1 */
let ex1_arr1 : [Any?] = ["foo", nil, 3, "bar"]
let ex1_arr2 : [Any?] = ["foo", nil, 3, "bar"]
compareAnyArrays(ex1_arr1, ex1_arr2) // true
/* Example usage #2 */
let ex2_arr1 : [Any?] = ["foo", nil, 2, "bar"]
let ex2_arr2 : [Any?] = ["foo", 3, 2, "bar"]
compareAnyArrays(ex2_arr1, ex2_arr2) // false