Multisplit: Difference between revisions

2,469 bytes added ,  4 years ago
→‎{{header|Python}}: Added a functionally composed draft (using reduce, without regexes)
(Add Factor)
(→‎{{header|Python}}: Added a functionally composed draft (using reduce, without regexes))
Line 1,439:
 
=={{header|Python}}==
===Procedural===
 
===Using Regularregular expressions===:
<lang python>>>> import re
>>> def ms2(txt="a!===b=!=c", sep=["==", "!=", "="]):
Line 1,457:
['a', (1, 1), '', (0, 3), '', (0, 4), 'b', (0, 6), '', (1, 7), 'c']</lang>
 
===Not using RE's===regular expressions:
'''Inspired by C-version'''
<lang python>def multisplit(text, sep):
Line 1,551:
multisplit(S, ["==", "!=", "="]) # output: ['a', [1, 1], '', [0, 3], 'b', [2, 6], '', [1, 7], 'c']
multisplit(S, ["=", "!=", "=="]) # output: ['a', [1, 1], '', [0, 3], '', [0, 4], 'b', [0, 6], '', [1, 7], 'c']</lang>
 
===Functional===
In terms of a fold (reduce), without use of regular expressions:
{{Works with|Python|3.7}}
<lang python>'''Multisplit'''
 
 
from functools import reduce
 
 
# multiSplit :: [String] -> String -> [(String, String, Int)]
def multiSplit(separators):
'''List of triples:
[(token, separator, start index of separator in string)].
'''
def go(s):
def f(tokensPartsOffset, ic):
tokens, parts, offset = tokensPartsOffset
i, c = ic
inDelim = offset > i
return maybe(
(tokens if inDelim else c + tokens, parts, offset)
)(
lambda x: ('', [(tokens, x, i)] + parts, i + len(x))
)(
Nothing() if inDelim else find(
s[i:].startswith
)(separators)
)
ts, ps, _ = reduce(f, enumerate(s), ('', [], 0))
return list(reversed(ps)) + [(ts, '', len(s))]
return go
 
 
# --------------------------TEST---------------------------
# main :: IO ()
def main():
'''String split on three successive separators.'''
print(
multiSplit(['==', '!=', '='])(
'a!===b=!=c'
)
)
 
 
# --------------------GENERIC FUNCTIONS--------------------
 
# Just :: a -> Maybe a
def Just(x):
'''Constructor for an inhabited Maybe (option type) value.
Wrapper containing the result of a computation.
'''
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
 
 
# Nothing :: Maybe a
def Nothing():
'''Constructor for an empty Maybe (option type) value.
Empty wrapper returned where a computation is not possible.
'''
return {'type': 'Maybe', 'Nothing': True}
 
 
# find :: (a -> Bool) -> [a] -> Maybe a
def find(p):
'''Just the first element in the list that matches p,
or Nothing if no elements match.
'''
def go(xs):
for x in xs:
if p(x):
return Just(x)
return Nothing()
return lambda xs: go(xs)
 
 
# maybe :: b -> (a -> b) -> Maybe a -> b
def maybe(v):
'''Either the default value v, if m is Nothing,
or the application of f to x,
where m is Just(x).
'''
return lambda f: lambda m: v if (
None is m or m.get('Nothing')
) else f(m.get('Just'))
 
 
# MAIN ---
if __name__ == '__main__':
main()</lang>
{{Out}}
<pre>[('a', '!=', 1), ('', '==', 3), ('b', '=', 6), ('', '!=', 7), ('c', '', 10)]</pre>
 
=={{header|Racket}}==
9,655

edits