2017年更新:香草JS的2行答案
这里的所有答案都过于复杂,大多数答案需要20行代码甚至更多行。
此示例仅使用两行原始JavaScript,没有lodash,下划线或其他库:
let f = (a, b) => [].concat(...a.map(a => b.map(b => [].concat(a, b))));
let cartesian = (a, b, ...c) => b ? cartesian(f(a, b), ...c) : a;
更新:
这与上述相同,但经过改进以严格遵循《Airbnb JavaScript样式指南》 -已通过ESLint和eslint-config-airbnb-base进行了验证:
const f = (a, b) => [].concat(...a.map(d => b.map(e => [].concat(d, e))));
const cartesian = (a, b, ...c) => (b ? cartesian(f(a, b), ...c) : a);
特别感谢ZuBB,让我知道了原始代码中的linter问题。
例
这是您提出的问题的确切示例:
let output = cartesian([1,2],[10,20],[100,200,300]);
输出量
这是该命令的输出:
[ [ 1, 10, 100 ],
[ 1, 10, 200 ],
[ 1, 10, 300 ],
[ 1, 20, 100 ],
[ 1, 20, 200 ],
[ 1, 20, 300 ],
[ 2, 10, 100 ],
[ 2, 10, 200 ],
[ 2, 10, 300 ],
[ 2, 20, 100 ],
[ 2, 20, 200 ],
[ 2, 20, 300 ] ]
演示版
观看演示:
句法
我在这里使用的语法并不新鲜。我的示例使用了散布运算符和其余参数-在2015年6月发布的ECMA-262标准的第6版中定义的JavaScript特性,该特性开发得更早,更广为人知的ES6或ES2015。看到:
它使这样的代码变得如此简单,以至于不使用它是一种罪过。对于本身不支持它的旧平台,您可以始终使用Babel或其他工具将其转换为较旧的语法-实际上,Babel转译的示例比此处的大多数示例短且简单,但是它不支持确实很重要,因为您无需了解或维护转译的输出,这只是我发现有趣的事实。
结论
当两行普通JavaScript可以轻松完成工作时,无需编写数百行难以维护的代码,也无需为整个过程使用整个库。如您所见,使用该语言的现代功能确实很有意义,并且在您需要支持古老平台而又没有对现代功能的本机支持的情况下,您始终可以使用Babel或其他工具将新语法转换为旧语法。
不要像1995年那样编码
JavaScript的发展是有原因的。TC39通过添加新功能在语言设计方面做得非常出色,而浏览器供应商在实现这些功能方面也做得非常出色。
要查看浏览器中任何给定功能的本机支持的当前状态,请参阅:
要查看Node版本中的支持,请参阅:
要在本身不支持现代语法的平台上使用现代语法,请使用Babel: