Swift扩展特定类型的数组

时间:2016-03-24 09:39:10

标签: arrays swift generics dictionary extension-methods

我正在尝试扩展具有字典作为元素的数组,其中字典的值是可比较的。它基本上就像一个自定义对象数组,并按特定的属性值对它们进行排序,只是在这种情况下,它是字典,而不是类实例。

可以看到数据结构为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:_]]?”不符合预期类型'任何'(又名'协议&lt;&gt;')

我怎样才能做到这一点?

ADDED

我做了以下内容,但是它受限于特定类型,因此我必须单独声明其他类型,如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 个答案:

答案 0 :(得分: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")

我是独立完成的,但是经过检查,它与你的第二个解决方案没有太大的不同。唯一的区别是,我们并不局限于字符串键。