刷到个比较有意思的场景题,就是平时我们在点菜的时候:热菜、微辣、中份、重麻的全部口味组合,在前端可能是不同下拉的数据源,需要组合成平铺的数据。比如:
javascript
const list = [['热', '冷', '冰'], ['大', '中', '小'], ['重辣', '微辣'], ['重麻', '微麻']];
// 要组合成
const r = [
"热+大+重辣+重麻",
"热+大+重辣+微麻",
"热+大+微辣+重麻",
"热+大+微辣+微麻",
"热+中+重辣+重麻",
"热+中+重辣+微麻",
"热+中+微辣+重麻",
"热+中+微辣+微麻",
"热+小+重辣+重麻",
"热+小+重辣+微麻",
"热+小+微辣+重麻",
"热+小+微辣+微麻",
"冷+大+重辣+重麻",
"冷+大+重辣+微麻",
"冷+大+微辣+重麻",
"冷+大+微辣+微麻",
"冷+中+重辣+重麻",
"冷+中+重辣+微麻",
"冷+中+微辣+重麻",
"冷+中+微辣+微麻",
"冷+小+重辣+重麻",
"冷+小+重辣+微麻",
"冷+小+微辣+重麻",
"冷+小+微辣+微麻",
"冰+大+重辣+重麻",
"冰+大+重辣+微麻",
"冰+大+微辣+重麻",
"冰+大+微辣+微麻",
"冰+中+重辣+重麻",
"冰+中+重辣+微麻",
"冰+中+微辣+重麻",
"冰+中+微辣+微麻",
"冰+小+重辣+重麻",
"冰+小+重辣+微麻",
"冰+小+微辣+重麻",
"冰+小+微辣+微麻"
]
这个简单场景可以先简化问题看:
- 如果只有 2 个类型
javascript
const [ ['热', '冷'], ['大', '小'] ];
// 用 2 个 for 循环,来输出所有组合
function fn(arr1, arr2) {
let r = [];
for (let x of arr1) {
for (let y of arr2) {
r.push(`${x} + ${y}`);
}
}
return r;
}
这样就会得到:['热 + 大', '热 + 小', '冷 + 大', '冷 + 小']
这样一个数组,那么我们再添加一个类型:['辣', '微辣', '微微辣']
,可以再调用一次 fn(['热 + 大', '热 + 小', '冷 + 大', '冷 + 小'], ['辣', '微辣', '微微辣'])
就可以得到结果啦。
这样就从当初三个数组元素变成了永远 2 个数组组合的模型 fn(fn(x + y), f(z))
,就比较经典了,就可以用以下方法来实现:
javascript
function compose(list) {
const len = list.length;
// 基础的函数模型,2 个数组的全组合
function fn(arr1, arr2) {
let r = [];
for (let x of arr1) {
for (let y of arr2) {
r.push(x + '+' + y);
}
}
return r;
}
// 我们先从第一个元素和第二个元素的值作为首项
let dp = fn(list[0], list[1]);
// 这里一定要从 i = 2 开始,因为 0~1 已经计算过了
for (let i = 2; i < len; i++) {
// 每次我们把上次已经计算好的组合数组,当作下一次计算的第一个元素,依次让他遍历完就可以了
dp = fn(dp, list[i]);
}
return dp;
}
const list = [['热', '冷', '冰'], ['大', '中', '小'], ['重辣', '微辣'], ['重麻', '微麻']];
const r = compose(list);
最后 r
就等于上面要的所有组合。
如果是暴力解法的话也是可以的,但是这样相当于有了个抽象函数,更加通用一点。
但是题目本身是解决这个问题,但是这个最好的交互还是应该列出类型,让点菜员自己去点出组合更好的,一般不会有需要列表的情况~除非是后台需要做一个检索。
所以最牛逼的口味还是热+大+重辣+重麻
...