Binary operator '==' cannot be applied to two operands
Update: SE-0143 Conditional conformances has been implemented in Swift 4.2.
As a consequence, your code does compile now. And if you define Item
as a struct
struct Item: Equatable { let item: [[Modifications: String]] init(item: [[Modifications: String]]) { self.item = item }}
then the compiler synthesizes the ==
operator automatically,compare SE-0185 Synthesizing Equatable and Hashable conformance
(Pre Swift 4.1 answer:)
The problem is that even if ==
is defined for the dictionary type[Modifications: String]
, that type does not conform toEquatable
. Therefore the array comparison operator
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool
cannot be applied to [[Modifications: String]]
.
A possible concise implementation of ==
for Item
would be
func ==(lhs: Item, rhs: Item) -> Bool { return lhs.item.count == rhs.item.count && !zip(lhs.item, rhs.item).contains {$0 != $1 }}
Your code compiles for [[String: String]]
– if the Foundationframework is imported, as @user3441734 correctly said – because then [String: String]
is automatically converted to NSDictionary
which conforms toEquatable
. Here is a "proof" for that claim:
func foo<T : Equatable>(obj :[T]) { print(obj.dynamicType)}// This does not compile:foo( [[Modifications: String]]() )// This compiles, and the output is "Array<NSDictionary>":foo( [[String: String]]() )
In your ==
function for Item
objects, you need to specify further how to compare two types of arrays of dictionaries (specifically, two types of [[Modifications: String]]
).
The following working solution compares your item
arrays element by element (dictionary by dictionary), and ==
returns true only if the arrays contain the same number of dictionaries, and if all entries are alike and ordered the same fashion in the array of dictionares
func ==(lhs: Item, rhs: Item) -> Bool { if lhs.item.count == rhs.item.count { for (i, lhsDict) in lhs.item.enumerate() { if lhsDict != rhs.item[i] { return false } } return true } else { return false }}class Item : Equatable { let item: [[Modifications: String]] init(item: [[Modifications: String]]) { self.item = item }}
You probably want to modify this into the form you actually want to use for comparison, but I hope you get the gist of it.
Note also that, if testing this in a playground, it's important that your ==
function definition func ==(lhs: Item, rhs: Item) -> Bool { ..
should precede your class definition, otherwise you will get an error of nonconformance to Equatable
.