简体   繁体   English

Haskell遍历列表

[英]Haskell iterate over a list

I know you suppose to think differently in Haskell, but can someone give me a quick answer on how to iterate over a list or nested list and print out a character based on the value of the list element. 我知道你想在Haskell中有不同的想法,但有人可以给我一个关于如何迭代列表或嵌套列表并根据列表元素的值打印出一个字符的快速答案。

list1 = [[1 0 0][0 1 0][0 0 1]]

By iterate through this nested list, it should print out x for 0 and y for 1 通过迭代这个嵌套列表,它应该打印x为0和y为1

yxx
xyx
xxy

Thanks 谢谢

First of all, I think you mean: 首先,我认为你的意思是:

list1 :: [[Int]]
list1 = [[1,0,0],[0,1,0],[0,0,1]]

As for what you want: 至于你想要什么:

valueOf :: Int -> Char
valueOf 0 = 'x'
valueOf 1 = 'y'
valueOf _ = 'z'

listValues :: [[Int]] -> [String]
listValues = map (map valueOf)

printValues :: [[Int]] -> IO ()
printValues = putStrLn . unlines . listValues

And then in ghci: 然后在ghci:

*Main> printValues list1 
yxx
xyx
xxy

Try this: 尝试这个:

fun :: [[Int]] -> [String]
fun = (map . map) (\x -> if x == 0 then 'x' else 'y')

If you really need printing of result: 如果你真的需要打印结果:

printSomeFancyList :: [[Int]] -> IO ()
printSomeFancyList = putStrLn . unlines . fun

define f by something like 用类似的东西来定义f

f x = if x == 0 then 'x' else 'y'

then 然后

map (map f) [[1,0,0],[0,1,0],[0,0,1]]

is what you want or if you want it fancier: 是你想要的,或者你想要它更高级:

map' = map.map
map' f [[1,0,0],[0,1,0],[0,0,1]]
iterateList = foldl1 (>>).concat.intersperse [putStrLn ""].(map.map) (\c ->  putStr $ if (c==0) then "X" else "Y")

The solutions using map are the preferred Haskell style. 使用map的解决方案是首选的Haskell风格。 But while you're learning, you may find explicit recursion easier to follow. 但是在学习的过程中,您可能会发现更容易理解的显式递归。 Like so: 像这样:

charSub :: Int -> Char
charSub 0 = 'x'
charSub 1 = 'y'
charSub x = error "Non-binary value!"

listSub :: [Int] -> String
listSub [] = []
listSub (x:xs) = (charSub x) : (listSub xs)

nestedSub :: [[Int]] -> String
nestedSub [] = []
nestedSub (y:ys) = (listSub y) ++ "\n" ++ (nestedSub ys) 

map does pretty much the same thing--it applies a function to each element in a list. map几乎完全相同 - 它将一个函数应用于列表中的每个元素。 But it may be easier to see what's going on here. 但是可能更容易看到这里发生了什么。

If you are interested in arbitrary nested lists, then you can write something like this (an arbitrary nested list is essentially a tree): 如果您对任意嵌套列表感兴趣,那么您可以编写类似这样的内容(任意嵌套列表本质上是一个树):

data Nested a = Leaf a | Nest [Nested a] deriving Show

traverse :: Nested Integer -> Nested Char
traverse (Leaf x) = Leaf (valueOf x)
traverse (Nest xs) = Nest (map traverse xs)

valueOf :: Integer -> Char
valueOf 0 = 'x'
valueOf 1 = 'y'
valueOf _ = 'z'

With that you can do: 有了这个你可以做:

Main> let nl = Nest [Leaf 1, Leaf 0, Nest [Leaf 0, Leaf 0, Leaf 1, Nest [Leaf 1, Leaf 1, Leaf 0]], Nest [Leaf 1, Leaf 1]]
Main> traverse nl
Nest [Leaf 'y',Leaf 'x',Nest [Leaf 'x',Leaf 'x',Leaf 'y',Nest [Leaf 'y',Leaf 'y',Leaf 'x']],Nest [Leaf 'y',Leaf 'y']]

The function traverse takes an arbitrary nested list of Integer s and returns a corresponding nested list of Char s according to the valueOf rule 函数traverse采用Integer的任意嵌套列表,并根据valueOf规则返回相应的Char s嵌套列表

解决方案

cambiar = putStr.unlines.(map (map f)) where f x = if x == 0 then 'x' else 'y'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM