Selectively replace multiple instances of a character within a string: Difference between revisions

→‎Python: Added a further variant ( a map-accumulation )
(→‎{{header|Haskell}}: Added a version in Haskell)
(→‎Python: Added a further variant ( a map-accumulation ))
Line 512:
],
)
)</lang>
)
</lang>
 
{{out}}
<pre>AErBcadCbFD</pre>
 
AErBcadCbFD
 
</pre>
Or, as a map-accumulation:
<lang python>from functools import reduce
 
 
# nthInstanceReplaced :: Dict Char [(None | Char)] ->
# String -> String
def nthInstanceReplaced(ruleMap):
def go(a, c):
i = a.get(c, 0)
deltas = ruleMap.get(c, [])
return (
dict(a, **{c: 1 + i}),
deltas[i] or c if i < len(deltas) else c
)
 
return lambda s: ''.join(
mapAccumL(go)({})(s)[1]
)
 
 
# ------------------------- TEST -------------------------
def main():
'''Rule-set applied to a given string.'''
 
print(
nthInstanceReplaced({
'a': ['A', 'B', None, 'C', 'D'],
'b': ['E'],
'r': [None, 'F']
})(
"abracadabra"
)
)
 
 
# ----------------------- GENERIC ------------------------
 
# mapAccumL :: (acc -> x -> (acc, y)) ->
# acc -> [x] -> (acc, [y])
def mapAccumL(f):
'''A tuple of an accumulation and a map
with accumulation from left to right.
'''
def go(a, x):
return second(lambda v: a[1] + [v])(
f(a[0], x)
)
return lambda acc: lambda xs: reduce(
go, xs, (acc, [])
)
 
 
# second :: (a -> b) -> ((c, a) -> (c, b))
def second(f):
'''A simple function lifted to a function over a tuple,
with f applied only to the second of two values.
'''
return lambda xy: (xy[0], f(xy[1]))
 
 
# MAIN ---
if __name__ == '__main__':
main()</lang>
{{Out}}
<pre>AErBcadCbFD</pre>
 
=={{header|Raku}}==
9,655

edits