2016-02-25 2 views
1

Я пытаюсь иметь словарь, который имеет строку как ключ и массив строки в качестве значения.
Тогда я хочу, чтобы проверить, если 2 из этих словарей, равны примерно так:Swift Словарь равенства массива строки

let dicOfStringStringAr1: [String : [String]] = ["key1" : ["val", "for key 1"]] 
let dicOfStringStringAr2: [String : [String]] = ["key1" : ["val", "for key 1"]] 
if dicOfStringStringAr1 == dicOfStringStringAr2 { 
    print("Dictionary of String Array") 
} 

Но я получаю эту ошибку:

error: binary operator '==' cannot be applied to two '[String : [String]]' operands

Но если значение строки вместо [String] это работает ,

let dicOfStringAr1: [String : String] = ["key1" : "val"] 
let dicOfStringAr2: [String : String] = ["key1" : "val"] 
if dicOfStringAr1 == dicOfStringAr2 { 
    print("Dictionary of String Array") 
} 

Я не понимаю проблемы.
Кто-то может объяснить, в чем проблема.


После просмотра по умолчанию == Swift функция словаря

@warn_unused_result 
public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool 

я понял, что нет никакого определения, где значение представлено в виде массива, а также о том, что «общее» Значение не может быть разрешенным к коллекции. (Не знаете, почему).
Итак, я сделал функцию ==, которая имела бы параметры [Key: [Value]]. И теперь код работает.

@warn_unused_result 
public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : [Value]], rhs: [Key : [Value]]) -> Bool { 
    var result = lhs.count == rhs.count 
    for (k, v) in lhs { 
     guard let arValue = rhs[k] where result == true else { 
      result = false 
      break 
     } 

     result = v == arValue 
    } 

    return result 
} 

Может кто-нибудь объяснить, почему в реализации Swift == значение не может быть разрешено для одного элемента, являющегося массивом?

ответ

1

Это на самом деле имеет смысл. Как вы можете видеть из функции == для типа <Key : Equatable, Value : Equatable>, для соответствия Equatable требуется Value. По умолчанию Array тип не соответствует Equatable. Обратите внимание, это не означает, что вы не можете сравнивать два массива с помощью ==.

[1, 2, 3] == ["a", "b", "c"] // false. 

Соответствует Equatable означает, что вы можете использовать ==, но не вице-стих.

Вы можете, конечно, расширить тип Array, чтобы он соответствовал Equatable.

extension Array: Equatable {} 
// Implement the following method. 
public func ==<T: CollectionType, U: CollectionType>(lhs: T, rhs: U) -> Bool {} 

Update

Я бы сказал, что это не возможно прямо сейчас, чтобы реализовать правдоподобное == для Array. (Возможно, это возможно в future swift version)

Для вашего конкретного случая я бы сказал, что следующий метод достаточно справедлив. Когда у вас есть пользовательский struct, просто убедитесь, что он соответствует Equatable.

public func ==<Key : Equatable, Value : CollectionType where Value.Generator.Element: Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool { 
    guard lhs.keys.elementsEqual(rhs.keys) else { return false } 

    for (key, value) in lhs { 
     if !value.elementsEqual(rhs[key]!) { return false } 
    } 

    return true 
} 

Пример будет:

struct Number: Equatable { 
    var x: Int 
    var y: Int 
} 

func ==(lhs: Number, rhs: Number) -> Bool { 
    return lhs.x == rhs.x && lhs.y == rhs.y 
} 

let dicOfStringStringAr1: [String : [Number]] = ["key1" : [Number(x: 1, y: 2), Number(x: 1, y: 2)]] 
let dicOfStringStringAr2: [String : [Number]] = ["key1" : [Number(x: 1, y: 2), Number(x: 1, y: 2)]] 
if dicOfStringStringAr1 == dicOfStringStringAr2 { 
    print("Dictionary of String Array") // "Dictionary of String Array" 
} 
+0

интересная идея, как бы вы реализовали свою функцию == как универсальную и безопасную для типа. Я пробовал '== ', чтобы ограничить доступ к функции только массивом, который мог бы сравните с ==, но также должны иметь '== ' для соответствия протокола. Проблема в том, что последний используется, поэтому я всегда получаю false. –

+0

Я расскажу о другом вопросе позже, чтобы изучить возможность того, чтобы эта работа была общей. Я добавлю новый комментарий, когда это будет сделано, если у вас есть идеи об этом. –

+0

Обновлен мой ответ. –

0

К счастью, вы можете проверить, равны ли эти словари, преобразовывая словарь в NSDictionary и используя его метод isEqualToDictionary. Например:

if NSDictionary(dictionary: dicOfStringStringAr1).isEqualToDictionary(dicOfStringStringAr2) { 
    print("Dictionary of String Array") 
} 
+0

это прогулка, которая будет работать только с объектами, если у меня есть массив структуры этот код сломается. Я ищу более общее решение. –

+0

Это была бы полезная информация, чтобы поставить на ваш вопрос – yesthisisjoe

+1

Спасибо, но я жестко сказал, что «у кого-то есть некоторый свет о том, в чем проблема». ясно дал понять, что меня больше интересует проблема, чем прогулка. Я обновил вопрос. Надеюсь, это избавит от двусмысленности. –

Смежные вопросы