June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
119
Task/Multisplit/JavaScript/multisplit-2.js
Normal file
119
Task/Multisplit/JavaScript/multisplit-2.js
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
(() => {
|
||||
|
||||
/// Delimiter list -> String -> list of parts, delimiters, offsets
|
||||
|
||||
// multiSplit :: [String] -> String ->
|
||||
// [{part::String, delim::String, offset::Int}]
|
||||
const multiSplit = (ds, s) => {
|
||||
const
|
||||
dcs = map(chars, ds),
|
||||
xs = chars(s),
|
||||
dct = foldl(
|
||||
(a, c, i, s) => {
|
||||
const
|
||||
inDelim = a.offset > i,
|
||||
mb = inDelim ? (
|
||||
nothing('')
|
||||
) : find(d => isPrefixOf(d, drop(i, xs)), dcs);
|
||||
return mb.nothing ? {
|
||||
tokens: a.tokens.concat(inDelim ? (
|
||||
[]
|
||||
) : [c]),
|
||||
parts: a.parts,
|
||||
offset: a.offset
|
||||
} : {
|
||||
tokens: [],
|
||||
parts: append(a.parts, [{
|
||||
part: intercalate('', a.tokens),
|
||||
delim: intercalate('', mb.just),
|
||||
offset: i
|
||||
}]),
|
||||
offset: i + length(mb.just)
|
||||
};
|
||||
}, {
|
||||
tokens: [],
|
||||
parts: [],
|
||||
offset: 0
|
||||
}, xs
|
||||
);
|
||||
return append(dct.parts, [{
|
||||
part: intercalate('', dct.tokens),
|
||||
delim: "",
|
||||
offset: length(s)
|
||||
}]);
|
||||
};
|
||||
|
||||
// GENERIC FUNCTIONS -----------------------------------------------------
|
||||
|
||||
// append (++) :: [a] -> [a] -> [a]
|
||||
const append = (xs, ys) => xs.concat(ys);
|
||||
|
||||
// chars :: String -> [Char]
|
||||
const chars = s => s.split('');
|
||||
|
||||
// drop :: Int -> [a] -> [a]
|
||||
// drop :: Int -> String -> String
|
||||
const drop = (n, xs) => xs.slice(n);
|
||||
|
||||
// find :: (a -> Bool) -> [a] -> Maybe a
|
||||
const find = (p, xs) => {
|
||||
for (var i = 0, lng = xs.length; i < lng; i++) {
|
||||
var x = xs[i];
|
||||
if (p(x)) return just(x);
|
||||
}
|
||||
return nothing('Not found');
|
||||
};
|
||||
|
||||
// foldl :: (a -> b -> a) -> a -> [b] -> a
|
||||
const foldl = (f, a, xs) => xs.reduce(f, a);
|
||||
|
||||
// intercalate :: String -> [String] -> String
|
||||
const intercalate = (s, xs) => xs.join(s);
|
||||
|
||||
// isPrefixOf takes two lists or strings and returns
|
||||
// true iff the first is a prefix of the second.
|
||||
// isPrefixOf :: [a] -> [a] -> Bool
|
||||
// isPrefixOf :: String -> String -> Bool
|
||||
const isPrefixOf = (xs, ys) => {
|
||||
const pfx = (xs, ys) => xs.length ? (
|
||||
ys.length ? xs[0] === ys[0] && pfx(
|
||||
xs.slice(1), ys.slice(1)
|
||||
) : false
|
||||
) : true;
|
||||
return typeof xs !== 'string' ? pfx(xs, ys) : ys.startsWith(xs);
|
||||
};
|
||||
|
||||
// just :: a -> Just a
|
||||
const just = x => ({
|
||||
nothing: false,
|
||||
just: x
|
||||
});
|
||||
|
||||
// length :: [a] -> Int
|
||||
const length = xs => xs.length;
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) => xs.map(f);
|
||||
|
||||
// nothing :: () -> Nothing
|
||||
const nothing = (optionalMsg) => ({
|
||||
nothing: true,
|
||||
msg: optionalMsg
|
||||
});
|
||||
|
||||
// show :: Int -> a -> Indented String
|
||||
// show :: a -> String
|
||||
const show = (...x) =>
|
||||
JSON.stringify.apply(
|
||||
null, x.length > 1 ? [x[1], null, x[0]] : x
|
||||
);
|
||||
|
||||
// TEST ------------------------------------------------------------------
|
||||
const
|
||||
strTest = 'a!===b=!=c',
|
||||
delims = ['==', '!=', '='];
|
||||
|
||||
return show(2,
|
||||
multiSplit(delims, strTest)
|
||||
);
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue