Selectively replace multiple instances of a character within a string: Difference between revisions
Selectively replace multiple instances of a character within a string (view source)
Revision as of 16:05, 28 July 2022
, 1 year ago→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▼
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}}==
|