Using Haskell:
假设我有列表:[1,3,4,2,3]
我想修改列表中的所有 3。我知道在这种情况下,我可以将其应用于选择 3:
map (x -> if p x then f x else x) xs
但是,应用于三的函数取决于它们在列表中的索引。
因此,例如,如果将索引添加到所需的数字,则我要要使用的函数的输出将是:[1,4,4,2,7]
。
您可以使用zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
来实现此目的:
zipWith(ix -> if p x then fix 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
,...(。
虽然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