Longest common prefix: Difference between revisions
Content added Content deleted
m (→{{header|Haskell}}: (swapped one <$> to an fmap, relieving the need for brackets)) |
(→{{header|JavaScript}}: Added an ES6 draft) |
||
Line 895: | Line 895: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
=== |
===ES5=== |
||
<lang JavaScript>(function () { |
<lang JavaScript>(function () { |
||
Line 994: | Line 994: | ||
} else return []; |
} else return []; |
||
}</lang> |
}</lang> |
||
===ES6=== |
|||
<lang javascript>(() => { |
|||
'use strict'; |
|||
// lcp :: (Eq a) => [[a]] -> [a] |
|||
const lcp = xs => { |
|||
const go = xs => |
|||
xs.some(isNull) ? ( |
|||
[] |
|||
) : cons( |
|||
map(head, xs), |
|||
go(map(tail, xs)) |
|||
); |
|||
return concat(map( |
|||
head, |
|||
takeWhile( |
|||
allSame, |
|||
go(map(chars, xs)) |
|||
) |
|||
)); |
|||
}; |
|||
// TEST --------------------------------------------- |
|||
// showPrefix :: [String] -> String |
|||
const showPrefix = xs => |
|||
concat([show(xs), ' --> ', show(lcp(xs))]); |
|||
// main :: IO () |
|||
const main = () => { |
|||
const strResults = unlines(map( |
|||
showPrefix, [ |
|||
["interspecies", "interstellar", "interstate"], |
|||
["throne", "throne"], |
|||
["throne", "dungeon"], |
|||
["cheese"], |
|||
[""], |
|||
["prefix", "suffix"], |
|||
["foo", "foobar"] |
|||
] |
|||
)); |
|||
return ( |
|||
// console.log(strResults), |
|||
strResults |
|||
); |
|||
}; |
|||
// GENERIC FUNCTIONS -------------------------------- |
|||
// allSame :: [a] -> Bool |
|||
const allSame = xs => |
|||
0 === xs.length || (() => { |
|||
const x = xs[0]; |
|||
return xs.every(y => x === y) |
|||
})(); |
|||
// chars :: String -> [Char] |
|||
const chars = s => s.split(''); |
|||
// concat :: [[a]] -> [a] |
|||
// concat :: [String] -> String |
|||
const concat = xs => |
|||
0 < xs.length ? (() => { |
|||
const unit = 'string' !== typeof xs[0] ? ( |
|||
[] |
|||
) : ''; |
|||
return unit.concat.apply(unit, xs); |
|||
})() : []; |
|||
// cons :: a -> [a] -> [a] |
|||
const cons = (x, xs) => [x].concat(xs); |
|||
// head :: [a] -> a |
|||
const head = xs => xs.length ? xs[0] : undefined; |
|||
// isNull :: [a] -> Bool |
|||
// isNull :: String -> Bool |
|||
const isNull = xs => |
|||
Array.isArray(xs) || ('string' === typeof xs) ? ( |
|||
1 > xs.length |
|||
) : undefined; |
|||
// map :: (a -> b) -> [a] -> [b] |
|||
const map = (f, xs) => |
|||
(Array.isArray(xs) ? ( |
|||
xs |
|||
) : xs.split('')).map(f); |
|||
// show :: a -> String |
|||
const show = JSON.stringify; |
|||
// tail :: [a] -> [a] |
|||
const tail = xs => 0 < xs.length ? xs.slice(1) : []; |
|||
// takeWhile :: (a -> Bool) -> [a] -> [a] |
|||
// takeWhile :: (Char -> Bool) -> String -> String |
|||
const takeWhile = (p, xs) => { |
|||
const lng = xs.length; |
|||
return 0 < lng ? xs.slice( |
|||
0, |
|||
until( |
|||
i => lng === i || !p(xs[i]), |
|||
i => 1 + i, |
|||
0 |
|||
) |
|||
) : []; |
|||
}; |
|||
// unlines :: [String] -> String |
|||
const unlines = xs => xs.join('\n'); |
|||
// until :: (a -> Bool) -> (a -> a) -> a -> a |
|||
const until = (p, f, x) => { |
|||
let v = x; |
|||
while (!p(v)) v = f(v); |
|||
return v; |
|||
}; |
|||
// MAIN --- |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>["interspecies","interstellar","interstate"] --> "inters" |
|||
["throne","throne"] --> "throne" |
|||
["throne","dungeon"] --> [] |
|||
["cheese"] --> "cheese" |
|||
[""] --> [] |
|||
["prefix","suffix"] --> [] |
|||
["foo","foobar"] --> "foo"</pre> |
|||
=={{header|jq}}== |
=={{header|jq}}== |