使用Haskell:
假设我有清单:[1,3,4,2,3]
我想修改列表中的所有3个。我知道在这种情况下我可以应用它来选择3:
map (\x -> if p x then f x else x) xs
但是,应用于三位数的函数取决于它们在列表中的索引。
因此,例如,如果将索引添加到所需的数字,我所要求的函数的输出将是:[1,4,4,2,7]
。
答案 0 :(得分:7)
您可以使用zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
:
zipWith (\i x -> if p x then f i x else x) [0..] xs
其中f
因此考虑i
(索引)和x
(元素)。
例如:
zipWith (\i x -> if x == 3 then (i+x) else x) [0..] xs
生成所需的输出:
Prelude> let xs = [1,3,4,2,3]
Prelude> zipWith (\i x -> if x == 3 then (i+x) else x) [0..] xs
[1,4,4,2,7]
您可以将此逻辑封装到单独的函数中,例如imap :: (Enum n, Num n) => (n -> a -> b) -> [a] -> b
:
imap :: (Enum n, Num n) => (n -> a -> b) -> [a] -> b
imap = flip zipWith [0..]
这适用于Num
和Enum
的实例的任何类型(所以Integer
,Int
,Float
,...)。
答案 1 :(得分:0)
虽然zipWith
可能是正确的方式,但对于各种类型,您可以按照以下方式递归;
tpi :: [Int] -> [Int]
tpi = runner 0
where runner _ [] = []
runner n (x:xs) | x == 3 = (n + x) : runner (n+1) xs
| otherwise = x : runner (n+1) xs