题目:
JavaScript 实现笛卡尔乘积,一般用于商品 sku 属性配置,例如输入 ['1', '2'], ['a', 'b'], ['+', '-', 'x'] ,输出 [ '1a+', '2a+', '1b+', '2b+', '1a-', '2a-', '1b-', '2b-', '1ax', '2ax', '1bx', '2bx' ]
解决方案:
case1
function mix(arr) {
const result = arr.reduce((accArr, currentArr) => {
let result = []
currentArr.forEach(c => {
if (accArr.length) {
accArr.forEach(a => {
result.push(a.concat(c))
})
} else {
result.push([c])
}
})
return result
}, [])
return result.map(arr => arr.join(''))
}
console.log(mix([['1', '2'], ['a', 'b'], ['+', '-', 'x']]))
case2
若:考察的是dfs全排列,而不是复杂reduce/map
const arr = [['1', '2'], ['a', 'b'], ['+', '-', 'x']]
function mix(arr) {
let cur = ''
let res = []
function search(deep = 0) {
if (deep >= arr.length) {
res.push(cur)
return
}
for (let o of arr[deep]) {
const tmp = cur
cur += o
search(deep + 1)
cur = tmp
}
}
search(0)
return res
}
console.log(mix(arr))
const mix = (arr) => arr
.reduce((acc, cur) => acc.length === 0
? cur
: acc
// 乘积
.map(x => cur.map(y => x + y))
// 拍平
.reduce((acc, cur) => acc.concat(cur), []),
[]
)
.join(', ')
const res = mix([['1', '2'], ['a', 'b'], ['+', '-', 'x']])
console.log(res)
// 其实如果固定参数数量的话这就是一个 Applicative Functor
List.of(x => y => z => [x, y, z].join(''))
.ap(List.of('1', '2'))
.ap(List.of('a', 'b'))
.ap(List.of('+', '-', 'x'))
.join(', ')
// 所以还可以顺便用 liftA3
liftA3
(x => y => z => [x, y, z].join(''))
(List.of('1', '2'))
(List.of('a', 'b'))
(List.of('+', '-', 'x'))
.join(', ')
const mix = (arr) => {
const help = (a,b) => {
if(!a.length) return b;
return a.map(e=>b.map(u=>e+u)).reduce((pre,e)=>pre.concat(e),[])
}
return arr.reduce((cur,e)=>help(cur,e),[])
}
console.log(mix([['1','2'],['a','b'],['+','-','x']]))