Selectively replace multiple instances of a character within a string: Difference between revisions
Content added Content deleted
(→{{header|Haskell}}: Added a version in Haskell) |
(→Python: Added a further variant ( a map-accumulation )) |
||
Line 512: | Line 512: | ||
], |
], |
||
) |
) |
||
⚫ | |||
) |
|||
⚫ | |||
{{out}} |
{{out}} |
||
<pre> |
<pre>AErBcadCbFD</pre> |
||
⚫ | |||
</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}} |
|||
⚫ | |||
=={{header|Raku}}== |
=={{header|Raku}}== |