2015-10-27 14 views
9

最後のステートメントがエラー:Binary operator '==' cannot be applied to two '[[Simple]]’ operandsでコンパイルに失敗し、Simple構造体を変更したり、ネストされた配列の等価チェックを実行できるようにする方法がありますまたは辞書)?ネストされた配列のスウィフト等価演算子

var i1: [Int] = [1] 
var i2: [Int] = [1] 
i1 == i2 // -> true 


var i3: [[Int]] = [[1], [2]] 
var i4: [[Int]] = [[1], [2]] 
i3 == i4 // -> true 


struct Simple: Equatable, Hashable { 
    let message: String 

    var hashValue: Int { 
     return message.hashValue 
    } 
} 
func ==(lhs: Simple, rhs: Simple) -> Bool { 
    return lhs.message == rhs.message 
} 

var a: [Simple] = [Simple(message: "a")] 
var b: [Simple] = [Simple(message: "a")] 
a == b // -> true 

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] 
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] 
x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]’ operands 

答えて

14

理由はWhy is Equatable not defined for optional arraysと同様です。要素型がEquatableであれば配列は==を比較することができます:なぜ

var a: [Simple] = [Simple(message: "a")] 
var b: [Simple] = [Simple(message: "a")] 
a == b // -> true 

コンパイルします

/// Returns true if these arrays contain the same elements. 
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool 

こと。

しかし、たとえequatable種類Tため、Array<T>Why can't I make Array conform to Equatable?を比較し、Equatableプロトコルにを準拠していません。したがって、

var x: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] 
var y: [[Simple]] = [[Simple(message: "a")], [Simple(message: "b")]] 
x == y // -> ERROR! Binary operator '==' cannot be applied to two '[[Simple]]’ operands 

xyEquatableプロトコルに準拠しない を行い要素型[Simple]有する配列であり、==オペレータに一致する は存在しません。

あなたは(@kennytmにより示唆されるように)単に

func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool { 
    return lhs.count == rhs.count && !zip(lhs, rhs).contains {$0 != $1 } 
} 

以上、単にネストされた配列のための一般的な==オペレータを定義することができます:予想通り

func ==<Element : Equatable> (lhs: [[Element]], rhs: [[Element]]) -> Bool { 
    return lhs.elementsEqual(rhs, by: ==) 
} 

これはx == yコンパイルと仕事になります。現在、任意のネストされた配列に対して==演算子を定義する方法は、 とは思われません。

  • スイフト4.1(現在開発中、snapshots available)のように:(スウィフトCHANGELOGから)

    The standard library types Optional, Array, and Dictionary now conform to the Equatable protocol when their element types conform to Equatable. ...

    。 これは、上記の回避策を時代遅れにします。

  • 一般的な条件適合は、SE-0143 Conditional conformancesで提案されているように、 はまだ実装されていません。

+0

おそらく実装を 'lhs.elementsEqual(rhs、by:==)'に更新しますか? – kennytm

+0

@kennytm:良い提案、ありがとう! –

+0

提案:完了:https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.mdはスウィフト4に含まれていないので、答え –

1

次のように、それのために==機能を実装することによってそれを行うことができます。

func == (lhs: [[Simple]], rhs: [[Simple]]) -> Bool { 
    //your code 
} 
+0

申し訳ありませんが、この質問はあなたの答えが意味するよりも複雑です。 – Jeff

+0

@ジェフあなたは意見を表明する権利がありますが、私はいつも複雑なものよりも簡単な解決法を好んでいます。 [YAGNI](https://en.wikipedia.org/wiki/You_aren't_gonna_need_it)がここに適用されます。 – Adam

+0

私のコメントは、不必要に複雑な答えを好むことに関するものではありませんでした。あなたの答えはこの質問の解決策ではありません。あなたの答えは不完全です。質問はあなたが理解しているよりも複雑です。 – Jeff

関連する問題