• 奇技淫巧
  • 仅用两行代码实现笛卡尔积,高效解决商品类型组合问题

笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尔积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。

使用场景

在程序设计领域笛卡尔乘积多用于多个属性组合描述某事物,例如在线购物时通过颜色、容量、重量来选择一部手机:

const source = [
  ['红', '黄', '蓝'],
  ['64G', '128G', '256G'],
  ['30kg', '100kg', '5kg'],
]

我们可以通过该数组组合得到 红-128G-100kg 这样一台手机,该数组可以组合出 27 种不同的配置,那么这个组合的过程我们就可以用笛卡尔乘积来处理。

思路解析

首先申明笛卡尔乘积函数,用于将两个一维数组进行组合:


const cartesianProduct = (prev, next) => prev.reduce((result, p) => [...result, ...next.map(n => p + n)], [])

然后遍历数据源,将数组种的前两个元素带入到上面的函数得出一个新的数组,再把得到的数组与第三个元素带入,以此迭代得到最终的结果:

source.reduce((result, item, i) => (i > 0 ? cartesianProduct(result, item) : result), source[0])

得益于 javascript 对数组操作的便利性,我们可以写出比大多数语言都要少量的代码

完整代码

const source = [
  ['红', '黄', '蓝'],
  ['64G', '128G', '256G'],
  ['4C', '8C', '16C'],
]

const cartesianProduct = (prev, next) => prev.reduce((result, p) => [...result, ...next.map(n => p + n)], [])
const r = source.reduce((result, item, i) => (i > 0 ? cartesianProduct(result, item) : result), source[0])

console.log(r)

运行效果

参考资料

https://baiyezi.com/2020/09/01/cartesian-product/