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}}==


===ES 5===
===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}}==