Swift 5字典分类的KeysbyValue
我需要从字典中获取按值排序的键列表 我发现这个问题很接近,但还不够好:Swift 5字典分类的KeysbyValue,swift,Swift,我需要从字典中获取按值排序的键列表 我发现这个问题很接近,但还不够好: 扩展字典{ func sortedKeysByValue(通过比较方法:(值,值)->Bool)->[键]{ 回归自我 .分类{ let(lk,lv)=0美元 出租(rk、rv)=1美元 返回比较法(lv、rv) } .地图{ 让(钥匙)=0美元 返回键 } } } 让dict=[“a”:5,“b”:3,“c”:10,“d”:7,“e”:9,“f”:5] 让结果=dict.keysSortedByValue(>) //结果可
扩展字典{
func sortedKeysByValue(通过比较方法:(值,值)->Bool)->[键]{
回归自我
.分类{
let(lk,lv)=0美元
出租(rk、rv)=1美元
返回比较法(lv、rv)
}
.地图{
让(钥匙)=0美元
返回键
}
}
}
让dict=[“a”:5,“b”:3,“c”:10,“d”:7,“e”:9,“f”:5]
让结果=dict.keysSortedByValue(>)
//结果可能是:
//[“c”、“e”、“d”、“a”、“f”、“b”]或
//[“c”、“e”、“d”、“f”、“a”、“b”]
问题是:当值相等时,它应该比较键以始终产生相同的结果。为此,我需要使用compareMethod
不仅接受值
类型,还接受键
类型。我试图使方法签名使用可比较的
协议,但得到一个编译错误:
扩展字典,其中键:可比,值:可比{
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^确保键/值类型具有可比性
func sortedKeysByValue(通过比较方法:(可比较,可比较)->Bool)->[Key]{
^^^^^^^^^^^^^^^^^^^^^出现错误(请参见下文)
回归自我
.分类{
let(lk,lv)=0美元
出租(rk、rv)=1美元
返回比较方法(lv,rv)| |(lv==rv&&compareMethod(lk,rk))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^值相等时比较键
}
.地图{
让(钥匙)=0美元
返回键
}
}
}
编译错误:协议“Compariable”只能用作一般约束,因为它具有自身或关联的类型要求
compareMethod
应该能够处理值
类型和键
类型。我怎么修理它
compareMethod应该能够处理值
类型和键
类型
不可能声明这样的函数。您需要一个函数来比较键,另一个函数来比较值
你可以这样写:
// doesn't have to be Comparable, just conforming to Equatable is fine, as you are only using "=="
extension Dictionary where Value: Equatable {
func sortedKeysByValue(byComparingValues compareValues: (Value, Value) -> Bool, andComparingKeys compareKeys: (Key, Key) -> Bool) -> [Key] {
return self
.sorted {
let (lk, lv) = $0
let (rk, rv) = $1
return compareValues(lv, rv) || (lv == rv && compareKeys(lk, rk))
}.map(\.key)
}
}
在我看来,更好的方法是使用(值,值)->ComparisonResult
函数,而不是(值,值)->Bool
。这不仅允许调用者指定其自定义的相等定义,而不是始终使用“==”,而且还使该方法可用于所有类型的词典
extension Dictionary {
func sortedKeysByValue(byComparingValues compareValues: (Value, Value) -> ComparisonResult, andComparingKeys compareKeys: (Key, Key) -> Bool) -> [Key] {
return self
.sorted {
let (lk, lv) = $0
let (rk, rv) = $1
switch compareValues(lv, rv) {
case .orderedAscending:
return false
case .orderedDescending:
return true
default:
return compareKeys(lk, rk)
}
}.map(\.key)
}
}
当然,缺点是你不能轻易地将一个比较运算符传递给这个问题。“我找到了一个接近这个问题的答案”Que!?你的问题是什么?谢谢你的回答<代码>??是打字错误;它应该是
&&
。单行代码应该是compareMethod(lv,rv)| |(lv==rv&&compareMethod(lk,rk))
。我更正了帖子@李岡諭 啊,这是有道理的。我不明白你为什么认为那里可以使用?
,哈哈。密钥已经符合Hashable。没有必要添加一个相等的约束。@LeoDabus哦,天哪,我真傻!我的大脑在晚上工作不好:)