笛卡尔乘积定义
- 笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尔积(Cartesian product),又称直积,表示为X×Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员。
- 假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
- 摘自百度百科
js实现笛卡尔乘积
const list = [
['热', '冷', '冰'],
['大', '中', '小'],
['全糖', '半糖'],
['现喝', '打包'],
];
// 根据 list 计算所有组合结果
let arr = [
'热大全糖现喝', '热大全糖打包', '热大半糖现喝',
'热大半糖打包', '热中全糖现喝', '热中全糖打包',
'热中半糖现喝', '热中半糖打包', '热小全糖现喝',
'热小全糖打包', '热小半糖现喝', '热小半糖打包',
'冷大全糖现喝', '冷大全糖打包', '冷大半糖现喝',
'冷大半糖打包', '冷中全糖现喝', '冷中全糖打包',
'冷中半糖现喝', '冷中半糖打包', '冷小全糖现喝',
'冷小全糖打包', '冷小半糖现喝', '冷小半糖打包',
'冰大全糖现喝', '冰大全糖打包', '冰大半糖现喝',
'冰大半糖打包', '冰中全糖现喝', '冰中全糖打包',
'冰中半糖现喝', '冰中半糖打包', '冰小全糖现喝',
'冰小全糖打包', '冰小半糖现喝', '冰小半糖打包'
]
思路
- 从原数组中取出前两项数组相互组合得到组合结果1
- 再利用组合结果1与原数组第三项数组相互组合得到结果2
- 依此类推,组合完原数组的所有数组项得到最终组合结果
实现代码
// 法一 const result = list.reduce((previousValue, currentValue) => { const next = []; for (let a of previousValue) { for (let b of currentValue) { next.push(a + b); } } return next; }); console.log('result', result); // 法二 const result2 = list.reduce((previousValue, currentValue) => { return previousValue.reduce((ret, a) => { ret.push(...currentValue.map(b => a + b)); return ret; }, []); }); console.log('result2',result2); // 法三 function combination (list) { let result = [] if (!list.length) return result // list长度为0时直接返回result for (let subList of list) { if (!result.length) { result = subList.map(item => [item]) } else { let subResult = [] for (let r of result) { let tailList = subList.map(item => r + item) // [...r,item] subResult.push(...tailList) } result = subResult } } return result } console.log("combination",combination(list))
Tips:reduce()语法
reduce()语法
arr.reduce(callback,[initialValue]) // callback 回调函数 // initialValue 初始值
callback
函数包含四个参数:previousValue
:上一次调用callback
时的返回值。在第一次调用时,若指定了初始值initialValue
,其值则为initialValue
,否则为数组索引为0的元素array[0]
currentValue
:数组中正在处理的元素。在第一次调用时,若指定了初始值initialValue
,其值则为数组索引为0的元素·,否则为array[1]
currentIndex
:数组中正在处理的元素的索引。若指定了初始值initialValue
,则起始索引号为0,否则从索引1起始。- array:用于遍历的数组
initialValue
(可选)- 作为第一次调用
callback
函数时参数previousValue
的值。若指定了初始值initialValue
,则currentValue
则将使用数组第一个元素;否则previousValue
将使用数组第一个元素,而currentValue
将使用数组第二个元素
- 作为第一次调用
reduce返回值
- 回调函数遍历整个数组后的结果