更新单个列表中的元素列表列表?

时间:2011-05-02 17:45:19

标签: list listview haskell replace

我有一些代码用于替换列表中的值

replaceNth n newVal (x:xs)
 | n == 0 = newVal:xs
 | otherwise = x:replaceNth (n-1) newVal xs

例如,当我将函数加载到GHCI中时,我输入并获取以下内容:

*Main> replaceNth 3 4 [3,3,3,3,3]
[3,3,3,4,3]

但是我试图将此函数用于列表中的多个列表,但似乎无法这样做(例如)。

我想要的是得到这样的结果:

[[3,3,3,3,3],[3,3,3,**2**,3],[3,3,3,3,3]]

由此[[3,3,3,3,3],[3,3,3,3,3],[3,3,3,3,3]]

使用类似上述功能的东西。

4 个答案:

答案 0 :(得分:3)

您的功能不够通用,无法处理您希望执行的任务。特别是,在调用函数之前,您需要知道之前的替换值是什么。要实现这一目标,您可以:

  • 选择第n个列表,计算新列表,然后使用您的函数将该替换放入列表列表中。 (以及更好)
  • 制定一个更通用的功能,而不是采用新值从旧值到新值:

示例

replaceNth' :: Int -> (a -> a) -> [a] -> [a]
replaceNth' n f (x:xs)
  | n == 0 = (f x):xs
  | otherwise = x:replace (n-1) f xs

现在解决第二个问题:

let ls = [[3,3,3,3,3],[3,3,3,3,3],[3,3,3,3,3]]
in replaceNth' 1 (replaceNth' 3 (const 2)) ls

这是用第二个列表取代一个列表,该列表取自该列表的第四个元素并用2代替它。

答案 1 :(得分:2)

创建一个函数,将函数应用于列表的第n个元素。然后你可以通过自己组合并使用const作为内部替换来轻松获得你想要的东西。

答案 2 :(得分:1)

也许这样做你想要的(应用于列表列表):

replaceNth 1 (replaceNth 3 4 [3,3,3,3,3])

答案 3 :(得分:0)

使用您现有的定义:

ghci> let arg = [[3,3,3,3,3],[3,3,3,3,3],[3,3,3,3,3]]
ghci> replaceNth 1 (replaceNth 3 2 (arg !! 1)) arg
[[3,3,3,3,3],[3,3,3,2,3],[3,3,3,3,3]]
ghci> 

将其重构为函数:

replaceMthNth m n v arg = replaceNth m (replaceNth n v (arg !! m)) arg