[英]Extract keys from map in a data type
我試圖在具有許多字段的數據類型中返回具有特定Status
鍵。 我嘗試了幾件事,但是什么都沒編譯! 有人知道我可以使用的小費嗎?
data Configuration v = Configuration {
configurationMap :: Map.Map v Status,
configurationGraph :: Graph v
}
verticesByStatus :: Ord v => Status -> Configuration v -> [v]
verticesByStatus ???
也許有一種更優雅的表達方式,但這是一個解決方案:
verticesByStatus status (Configuration map graph) = fst <$> (filter ((== status) . snd) $ M.assocs map)
那么這是怎么回事? 首先,我們對配置參數進行模式匹配以提取其兩個組成部分,並將其分配給變量map
和graph
。 現在讓我們分解右側:
fst <$> (filter ((== status) . snd) $ Map.assocs map)
^-- This comes from the Data.Map package and splits a map into a list of tuples of key/value pairs.
^-- Here, we filter our new list of key/values based on the values, and find only those that match the input status
^-- Last, we fmap the function fst over the whole list to extract only the keys that match your given status
表達此功能的另一種方法是通過eta簡化將其簡化。 一種方法是使用configurationMap
函數提取configurationMap
該部分而不是模式匹配:
verticesByStatus status = fmap fst . filter ((== status) . snd) . Map.assocs . configurationMap
Data.Map
有一個映射filter
,可以直接與您的配置映射一起使用:
verticesByStatus :: Ord v => Status -> Configuration v -> [v]
verticesByStatus status = Map.keys . Map.filter (== status) . configurationMap
Map.keys
生成地圖中的鍵列表。 (如果你想值的列表,而不是,您可以使用Map.elems
或者等價地, toList
從Data.Foldable
。需要注意的是,有些令人混淆,后者是不一樣的Map.toList
,產生密鑰列表值對,就像Map.assocs
在jkeuhlen的答案。)
verticesByStatus :: Ord v => Status -> Configuration v -> [v]
verticesByStatus status (Configuration cMap cGraph) =
[ v
| v <- vertices cGraph,
Just(status) == (Map.lookup v cMap)]
一些注意事項:
我選擇避免使用Map.assocs
因為它要花費額外的O(n)來運行,您可以在配置映射中獲取值,而無需先將其轉換為元組列表(請參閱Map docs )。
我選擇了列表理解功能,而不是將map
和filter
組合在一起而不是出於個人喜好,因為我發現它更易於閱讀(在閱讀本文后我發現了這一點 )
相反,我們可以檢查查詢是否返回了Just
或Nothing
,然后在使用fromJust
的Just
情況下提取了該值,但這將是更多的代碼並且可能更難閱讀。 它看起來像:
verticesByStatus :: Ord v => Status -> Configuration v -> [v] verticesByStatus status (Configuration cMap cGraph) = [ v | v <- vertices cGraph, let vStatus = Map.lookup v cMap, if (isJust vStatus) then (status == (fromJust vStatus)) else False]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.