假设我有一个像这样的列表:
list= [["a","123","b"],["h","435","t"],["w","234","j"]]
我需要的是将该列表列表的每个第二个成员转换为Integer
,因为它将在此之后用作大小指示符,因此我可以按大小对列表进行排序。
我想出了一个转换功能:
charToInt c = ord (chr c)
但我不知道如何转换列表中的每个第二个成员。
答案 0 :(得分:6)
要扩展Paul Johnson所说的内容,您需要为您尝试保留的数据定义数据类型。
data MusicFile = MusicFile {music :: String,
size :: Integer,
artist :: String}
deriving Show
musicFileFromStrings :: [String] -> MusicFile
musicFileFromStrings [sMusic, sSize, sArtist]
= MusicFile sMusic (read sSize) sArtist
然后,如果你有
list = [["a","123","b"],["h","435","t"],["w","234","j"]]
你可以说
anotherList = map musicFileFromStrings list
然后
map music anotherList -- ["a", "h", "w"]
map artist anotherList -- ["b", "t", "j"]
(编辑)
如果您想按特定字段对列表进行排序,可以使用“sortBy”和“comparing”。
import Data.List
import Data.Ord
sizeOrderList = sortBy (comparing size) anotherList
“比较”功能将一个值(在本例中为“大小”)的函数转换为两个值之间的比较函数。唯一的要求是“size”的输出(在这种情况下)是一个“Ord”实例的类型。
如果您想降序而不是使用
sizeOrderList = sortBy (comparing (flip size)) anotherList
答案 1 :(得分:4)
您无法将内部列表的第二个元素转换为Integer
,而无需将列表中的类型更改为元组之类的内容。原因是列表在Haskell中是同构的,因此您需要一个元组来表示混合类型。
将String
转换为Integer
的方法如下:
read "123" :: Integer
您需要直接添加类型,因为read
的类型为Read a => String -> a
,这意味着它会返回某种类型的内容,可以是" read"。幸运的是,Integer
是该类型类的成员,因此我们可以将String
转换为Integer
。
现在转换每个内部列表的第二个元素只是一个简单的事情:
convert :: [[String]] -> [(String, Integer, String)]
convert lists = map (\[a, b, c] -> (a, read b, c)) lists