[英]Replacing element in a list of lists in Haskell
I have a list of lists like so: 我有一个像这样的清单清单:
[["BBBBBBBB",
"BWFFFPFGB",
"BWFFFPFGB",
"BWFFMPFGB",
"BWFFFPF_B",
"BWFFFPF6B",
"BBBBBBB"]]
I've done a little research and have found out how to access individual elements using the !!
我做了一些研究,发现了如何使用
!!
访问各个元素!!
operator. 操作员。 But when it comes to searching for a certain element
'M'
I'm not sure how to go about that. 但是,当要搜索某个元素
'M'
我不确定该怎么做。 My friend said I need to use something like (x:xs):xss
on a list, but when I try this in the WinGHCi haskell program I get this. 我的朋友说我需要在列表上使用
(x:xs):xss
类的东西,但是当我在WinGHCi haskell程序中尝试此操作时,会得到此信息。
Prelude> let list = [["BBBBBBBB",
"BWFFFPFGB",
"BWFFFPFGB",
"BWFFMPFGB",
"BWFFFPF_B",
"BWFFFPF6B",
"BBBBBBB"]]
Prelude> head(x:xs):xss
<interactive>:192:2: Not in scope: `x'
<interactive>:192:4: Not in scope: `xs'
<interactive>:192:8: Not in scope: `xss'
I understand that I declare the name as list
and not x:xs
but even when I declare it as x:xs
I still get the errors. 我知道我将名称声明为
list
而不是x:xs
但是即使将其声明为x:xs
我仍然会收到错误消息。 I'm probably still a little new to haskell to really understand what to do so I may be going about this way wrong. 我可能对Haskell还是有点陌生,可以真正理解该怎么做,所以我可能会出错。
I've looked here Replace individual list elements in Haskell? 我在这里查看了替换Haskell中的单个列表元素? because eventually I want to replace the
M
with something different but I'm not completely sure how I would implement that. 因为最终我想用不同的东西替换
M
,但是我不确定如何实现。
Any help/guidance is appreciated, thanks! 任何帮助/指导表示赞赏,谢谢!
First of all, virtually all "variables" in Haskell are immutable, so there's no "changing a list", there are modified copies. 首先,Haskell中几乎所有“变量”都是不可变的,因此没有“更改列表”,而是经过修改的副本。
Second, you need to find an element by some criteria. 其次,您需要根据一些条件来查找元素。 To do that, you need to traverse a list.
为此,您需要遍历列表。 - This can be done using recursion.
-这可以使用递归来完成。 Filtering can be done using a function passed as an argument of your traversing function (this function must take an element and return a boolean value).
可以使用作为遍历函数的参数传递的函数来完成过滤(该函数必须带有一个元素并返回一个布尔值)。
Try to put the above together and make your own function. 尝试将以上内容放在一起并发挥自己的作用。 Start with a type signature, it shows what you want to do: to take a list of Char (it's better to generalize to a generic type) and a function which possibly changes an element and return a modified list:
从类型签名开始,它显示了您要执行的操作:获取Char列表(最好将其泛化为通用类型)和一个可能更改元素并返回修改后列表的函数:
replaceFunc :: (Char -> Char) -> String -> String replaceFunc ::(字符->字符)->字符串->字符串
Also, read http://www.haskell.org/haskellwiki/How_to_work_on_lists , there's a hint there how to apply some function to specific elements only. 另外,请阅读http://www.haskell.org/haskellwiki/How_to_work_on_lists ,这里有一个提示,指出如何仅将某些功能应用于特定元素。
First let's see how to replace a W
with M
首先让我们看看如何用
M
替换W
charWM :: Char -> Char
charWM 'W' = 'M' -- If you see W, put M.
charWM x = x -- If you see anything else, put it back as is.
You can rewrite that function how you like by adding other letter transformations. 您可以通过添加其他字母转换来以自己喜欢的方式重写该函数。
Now let's make that work over a list. 现在,让我们在列表上进行操作。 There's a great function
map :: (a ->b) -> [a] -> [b]
that lets you apply a function on every element on a list. 有一个很棒的功能
map :: (a ->b) -> [a] -> [b]
,可让您在列表上的每个元素上应用功能。
stringWM :: String -> String
stringWM xs = map charWM xs -- do charWM to everything in xs.
For example stringWM "QWERTY WILL WIN"
= "QMERTY MILL MIN"
例如
stringWM "QWERTY WILL WIN"
= "QMERTY MILL MIN"
Next we can do that to a list of lists: 接下来,我们可以对列表进行操作:
lolWM :: [String] -> [String]
lolWM xss = map stringWM xss
( String
is a type synonym for [Char]
.) (
String
是[Char]
的类型同义词。)
Let's test that out in ghci: 让我们在ghci中测试一下:
*Main> list'
["BBBBBBBB","BWFFFPFGB","BWFFFPFGB","BWFFMPFGB","BWFFFPF_B","BWFFFPF6B","BBBBBBB"]
*Main> lolWM list'
["BBBBBBBB","BMFFFPFGB","BMFFFPFGB","BMFFMPFGB","BMFFFPF_B","BMFFFPF6B","BBBBBBB"]
All good. 都好。
Your example wasn't exactly list'
, it was [list']
which has 1 element, so to work on that we'd need to map lolWM
. 您的示例并非完全是
list'
,而是[list']
具有1个元素,因此要进行工作,我们需要map lolWM
。 Often we wouldn't bother writing stringWM
or lolWM
and go directly to lists of lists of lists, if that's what we needed: 如果我们需要的话,通常我们不会费心编写
stringWM
或lolWM
并直接进入列表列表的列表:
lololWM = (map.map.map) charWM
map.map.map
means map the map of the map. map.map.map
表示地图的地图。 You can allow that to blow your mind a little, or you can just say list of list of list of Char, so map map map - one map per list level. 您可以让您大吃一惊,也可以只说Char列表的列表列表,所以可以使用map map map-每个列表级别一个map。
In the future, maybe you'll want to replace W
with Strings instead of characters. 将来,也许您会想用String代替字符替换
W
rewriteChar :: Char -> String
rewriteChar 'W' = "--^--"
rewriteChar x = [x] -- put x in a list to make it a string
This time, map isn't enough: map rewriteChar "QWERTY WILL WIN"
gives 这次,地图还不够:
map rewriteChar "QWERTY WILL WIN"
给
["Q","--^--","E","R","T","Y"," ","--^--","I","L","L"," ","--^--","I","N"]
We could use concat
on that to flatten it into a single list, but it's more fun to do 我们可以在其上使用
concat
将其展平为一个列表,但是这样做更有趣
rewriteString = concatMap rewriteChar
So now rewriteString "QWERTY WILL WIN"
give us "Q--^--ERTY --^--ILL --^--IN"
. 所以现在
rewriteString "QWERTY WILL WIN"
给我们"Q--^--ERTY --^--ILL --^--IN"
。
For more mindblowing things to try, there's "QWERTY WILL WIN" >>= rewriteChar
and "Hello Mum" >>= \\x -> [x,x,x]
要尝试更多
"QWERTY WILL WIN" >>= rewriteChar
事情,请使用"QWERTY WILL WIN" >>= rewriteChar
和"Hello Mum" >>= \\x -> [x,x,x]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.