JavaScript 实现笛卡尔乘积

2019-05-24  本文已影响0人  宫若石

题目:
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']]))
上一篇 下一篇

猜你喜欢

热点阅读