Cartesian product of two or more lists: Difference between revisions

→‎Functional JS: Updated n-ary version.
(→‎Functional JS: Updated n-ary version.)
Line 1,162:
For the n-ary Cartesian product over a list of lists:
<lang JavaScript>(() => {
const unlinesmain = xs() => xs.join('\n');{
// n-ary Cartesian product of a list of lists.
 
// cartProdN :: [[a]] -> [[a]]
const cartProdN = lists =>foldr(
foldr((as, xs) => as =>
bind(xs, x => bind(as, a => [x.concat)(a)])), [
[]x => bind(xs)(
], lists a => [[a].concat(x);]
[30], )
[],)
])([[]]),;
 
// GENERIC FUNCTIONSTEST ------------------------------------------------------
return intercalate('\n\n', [unlines(map(show, cartProdN)([
[7, 12],map(show)(
show( cartProdN([
[1776, 1789],
[07, 112],
[4, 14, 23],
[500, 1001]
[1, 2, 3 ],)
[1, 2, 3]).join('\n'),
show(cartProdN([
[501, 1002, 3],
[30]))),
[50, 100]
])),
show(cartProdN([
[1, 2, 3],
[],
[50, 100]
]))
])
};
 
// TESTGENERIC FUNCTIONS -------------------------------------------------------------------
 
// bind :: [a] -> (a -> [b]) -> [b]
const bind = (xs, => f) => [].concat.apply([], xs.mapflatMap(f));
 
// foldr :: (a -> b -> b) -> b -> [a] -> b
const foldr = (f, => a, xs) => xs.reduceRight(f, a);=> {
let v = a,
i = xs.length;
while (i--) v = f(xs[i])(v);
return v;
};
 
// intercalate :: String -> [a] -> String
const intercalate = (s, => xs) => xs.join(s);
 
// map :: (a -> b) -> [a] -> [b]
const map = (f, => xs) => xs.map(f);
 
// show :: a -> String
const show = x => JSON.stringify(x);
 
return main();
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
 
// TEST -------------------------------------------------------------------
return intercalate('\n\n', [unlines(map(show, cartProdN([
[1776, 1789],
[7, 12],
[4, 14, 23],
[0, 1]
]))),
show(cartProdN([
[1, 2, 3],
[30],
[50, 100]
])),
show(cartProdN([
[1, 2, 3],
[],
[50, 100]
]))
])
})();</lang>
{{Out}}
9,659

edits