2016-03-24 2 views
0

Я пытаюсь расширить массивы со словарями в качестве элементов, где значения словарей сопоставимы. Это в основном как массив пользовательских объектов и сортировка их по определенным значениям свойств, только в этом случае это словари, а не экземпляры классов.Быстрое расширение Массив определенного типа

Можно увидеть структуру данных как Array<Dictionary<Key: Hashable, Value: Comparable>>, хотя предыдущий код не поддерживается ..

Я думаю, что речь идет близко к работе, но не может по разным причинам.

Мои первые попытки были

extension ArrayLiteralConvertible where Element == Dictionary<String, Comparable> { 
    func sortByKey<T: Comparable>(key: String, ascending: Bool) -> [[String: T]]? { 
     if let dictType = self as? [[String: T]] { 
      return ascending ? dictType.sort { return $0[key] < $1[key] } : dictType.sort { return $0[key] > $1[key] } 
     } else { 
      return nil 
     } 
    } 
} 

Это работает в декларации, но при использовании, он выдает ошибку

словарь не конвертируется в '[String: Int]

Еще одна попытка:

extension SequenceType where Generator.Element == [String: AnyObject] { 
    func sortByKey<T: Comparable>(key: String, ascending: Bool) -> [[String: T]]? { 
     if let dictType = self as? [[String: T]] { 
      return ascending ? dictType.sort { return $0[key] < $1[key] } : dictType.sort { return $0[key] > $1[key] } 
     } else { 
      return nil 
     } 
    } 
} 

возвращает

Аргумент типа "[[String: _]]?" не соответствует ожидаемому типу «Любой» (ака 'протокол <>')

Как я могу сделать эту работу?

ДОБАВЛЕНО

я сделал-делать со следующим, но он ограничен конкретным типом, так что я должен объявить отдельно для других типов, таких как строки ..

extension ArrayLiteralConvertible where Element == [String: Int] { 
    func sortByKey(key: String, ascending: Bool) -> [[String: Int]] { 
     let arraySelf = self as! [[String: Int]] 
     return ascending ? arraySelf.sort { return $0[key] < $1[key] } : arraySelf.sort { return $0[key] > $1[key] } 
    } 
} 

Другой вариант:

func sortArray<T: Comparable>(array: [[String: T]], byKey key: String, ascending: Bool) -> [[String: T]] { 
    return ascending ? array.sort { return $0[key] < $1[key] } : array.sort { return $0[key] > $1[key] } 
} 

ответ

1

Я думаю, вы сделали очень хорошо. Я не знаю, если вы, как это лучше:

func sortedArrayOfDictionaries<T:Comparable>(arr:[[NSObject:T]], byKey key:NSObject) -> [[NSObject:T]] { 
    return arr.sort({ (d1, d2) -> Bool in 
     return d1[key] < d2[key] 
    }) 
} 

Чтобы использовать его, вы должны отдать свой первоначальный массив, так что ключ типа NSObject:

let arr : [[NSObject:Int]] = [["hey":2], ["hey":1]] 
let arr2 = sortedArrayOfDictionaries(arr, byKey: "hey") 

Я прибыл в что независимо, но при осмотре он существенно не отличается от вашего второго решения. На самом деле единственное отличие состоит в том, что мы не ограничены строковым ключом.