1. 程式人生 > >JS幾道演算法題

JS幾道演算法題

笛卡爾乘積

示例輸入:['1', '2'], ['a', 'b'], ['+', '-', 'x'] 示例輸出:["1a+", "1a-", "1ax", "1b+", "1b-", "1bx", "2a+", "2a-", "2ax", "2b+", "2b-", "2bx"] 程式碼:

// 中規中矩的思路,用 reduce 迭代每個 item
let Descartes = (...items) => items.reduce((acc, cur) => {
        let ret = []
        if (!acc.length) {
            acc = cur
        } else
{ acc.forEach(i => { cur.forEach(j => { ret.push(i + j) }) }) } return ret })

比較牛逼的程式碼:

// 已有的笛卡爾積結果 map 新元素的各項
let Descartes = (...items) => items.reduce((acc, cur) => (!acc.length) ? cur : acc.map(e => cur.map(u => e + u)).reduce((pre, e) => pre.concat(e), []), [])

判斷連續區間

判斷一組數字是否連續,並將連續的部分以區間的形式展示 示例輸入:[1, 2, 3, 4, 6, 8, 9, 10] 示例輸出:["1-4", 6, "8-10"] 程式碼:

// 先聚合為連續區間的二維陣列,再 map 展示之
let isContinuous = arr => arr.reduce((acc, cur, idx, arr) => idx === 0 
    ? [ ...acc, [cur] ]
    : arr[idx - 1] + 1 === arr[idx]
      ? acc.concat([ acc.pop().slice(0
, 1).concat(cur) ]) : [ ...acc, [cur] ], [] )
.map(x => Array.isArray(x) ? x.join('-') : x)

關係陣列轉換為樹

示例輸入:

var obj = [
  { id:3, parent: null },
  { id:1, parent: 2 },
  { id:2, parent: 3 },
]

示例輸出:

{
  id: 3,
  parent: null,
  child: {
    id: 2,
    parent: 3,
    child: {
      id: 1,
      parent: 2
    }
  }
}

程式碼:

// 先根據 parent 的關係排個序,然後 reduce 遍歷一遍生成結果
let target = null
const sortedArr = []
while (sortedArr.length < obj.length) {
  const item = obj.find(x => x.parent === target)
  target = item.id
  sortedArr.unshift(item)
}
sortedArr.reduce((acc, cur) => (acc ? { ...cur, child: acc } : cur))