筆試記錄集

water_發表於2018-04-22

記錄一些在筆試過程中遇到的題目,做法不一定對,如果你對於題目有其他想法,歡迎討論。

1、實現一個Event類,on為監聽事件,trigger觸發事件,off消除事件

class Event {
  constructor() {
    this._cache = {}
  }
  on(type, cb) {
    let fns = (this._cache[type] = this._cache[type] || [])
    if (fns.indexOf(cb) === -1) {
      fns.push(cb)
    }
    return this
  }
  trigger(type, data) {
    let fns = this._cache[type]
    if (Array.isArray(fns)) {
      fns.forEach(fn => {
        fn(data)
      })
    }
    return this
  }
  off(type, cb) {
    let fns = this._cache[type]
    if (Array.isArray(fns)) {
      if (cb) {
        let index = fns.indexOf(cb)
        if (index !== -1) {
          fns.splice(index, 1)
        }
      } else {
        fns.length = 0
      }
    }
    return this
  }
}

const event = new Event()

event.on('test', a => {
  console.log(a)
})
event.trigger('test', 'water')
event.off('test')
event.trigger('test', 'hello world')
複製程式碼

2、給出一個整數,實現一個函式,輸出該整數的千分位劃分,如12345,輸出12,345

// 正則 零寬斷言
function exchange(num) {
  num += ''
  if (num.length <= 3) return num
  num = num.replace(/\d{1,3}(?=(\d{3})+$)/g, function(v) {
    return v + ','
  })
  return num
}
console.log(exchange(1234567))

//
const num = 2333333
num.toLocaleString()
複製程式碼

3、假設你有一個函式,產生[0, 5)之間的隨機整數,每個數字概率1/5,如何使用這個函式產生[0, 7)之間的隨機整數,每個數字概率1/7

/**
利用rand5()函式生成1-25之間的數字,然後將其中的1-21對映成1-7,丟棄22-25。
**/
function rand7() {
	var res = 0
	do {
		res = (rand5() - 1) * 5 + rand5()
	} while(res > 21)
	return 1 + res % 7
}
複製程式碼

4、完成方法shuffle(arr),傳入陣列arr,返回隨機打亂後的陣列

function shuffle(arr) {
  return arr.sort(function() {
    return Math.random() - 0.5
  })
}
複製程式碼

5、完成方法count(str),傳入字串,返回字串中出現次數最多的字元及次數

function count(str) {
  return [...new Set(str.split(''))]
          .map(v => [v, str.match(new RegExp(v, 'g')).length])
          .sort((a, b) => b[1] - a[1])
          .slice(0, 1)
}
複製程式碼

6、完成方法subset(arr1,arr2),傳入兩個陣列,判斷陣列arr1是否為陣列arr2的子集

function subset(arr1, arr2) {
  if ((!arr1 instanceof Array) || (!arr2 instanceof Array)) return false
  if (arr2.length < arr1.length) return false
  for (let i = 0, len = arr1.length; i < len; i++) {
    if (arr2.indexOf(arr1[i]) === -1) return false
  }
  return true
}
複製程式碼

7、有一個陣列,定義一個函式,傳入arr後,返回值為一個二維陣列:

const arr = [[1,2],3,[4,5,6]];

[[1,3,4],[2,3,4],[1,3,5],[2,3,5],[1,3,6],[2,3,6]]
複製程式碼
function multiply(arr) {
  let ret = []

  function cur(result, index) {
    if (index === -1) {
      ret.push(result)
    } else {
      let items = Array.isArray(arr[index]) ? arr[index] : [arr[index]]
      items.forEach(item => {
        cur([item, ...result], index - 1)
      })
    }
  }
  cur([], arr.length - 1)
  return ret
}
const arr = [
  [1, 2], 3, [4, 5, 6]
];
console.log(multiply(arr))
複製程式碼

8、前端路由的簡單實現

function Router() {
  this.routes = {}
  this.currentUrl = ''
}
Router.prototype.route = function(path, callback) {
  this.routes[path] = callback || function() {}
}

Router.prototype.refresh = function() {
  this.currentUrl = location.hash.slice(1) || '/'
  this.routes[this.currentUrl]()
}

Router.prototype.init = function() {
  window.addEventListener('load', this.refresh.bind(this), false)
  window.addEventListener('hashchange', this.refresh.bind(this), false)
}
window.Router = new Router()
window.Router.init()
Router.route('/', function() {
  console.log('white')
})
Router.route('/blue', function() {
  console.log('blue')
})
Router.route('/green', function() {
  console.log('green')
})
複製程式碼

9、有一個已經排序的陣列,比方[1,4,6,9,11,15,18],給你一個新的數,插入到陣列中

var arr = [1, 4, 6, 9, 11, 15, 18]

function arrIndexOf(arr, val) {
  var mid,
    min = 0,
    max = arr.length - 1
  while (min <= max) {
    mid = (min + max) >> 1
    if (val > arr[mid]) {
      min = mid + 1
    } else if (val < arr[mid]) {
      max = mid - 1
    } else {
      return mid
    }
  }
  return min
}

function insert(arr, val) {
  if (arr[0] === val) {
    arr.unshift(val)
  } else if (arr[arr.length - 1] === val) {
    arr.push(val)
  } else {
    arr.splice(arrIndexOf(arr, val), 0, val)
  }
  return arr
}


// or

function insert(arr, val) {
  arr.push(val)
  return arr.sort((a, b) => {
    return a - b
  })
}

複製程式碼

10、實現HardMan類,符合以下要求

HardMan("jack")
// 輸出 'I am jack'
HardMan("jack").rest(10).learn("computer")
// 輸出 'I am jack'
// 10s後輸出
// 'Start learning after 10 second'
// 'Learning computer'
HardMan("jack").restFirst(5).learn("chinese")
// 5s後輸出
// 'Start learning after 5 second'
// 'I am jack'
// 'Learning chinese'
複製程式碼
const HardMan = name => {
  class HardMan {
    constructor(name) {
      this.queue = [this.init(name)]
      setTimeout(async () => {
        for (let todo of this.queue) {
          await todo()
        }
      }, 0)
    }
    init(name) {
      return () => console.log(`I am ${name}`)
    }
    learn(subject) {
      this.queue.push(() => console.log(`Learning ${subject}`))
      // 鏈式呼叫
      return this
    }
    holdon(time) {
      return () => new Promise(resolve => setTimeout(() => {
        resolve(console.log(`Start learning after ${time} second`))
      }, time * 1000))
    }
    rest(time) {
      this.queue.push(this.holdon(time))
      return this
    }
    restFirst(time) {
      this.queue.unshift(this.holdon(time))
      return this
    }
  }
  return new HardMan(name)
}
複製程式碼

11、套待出租的房子,價格分別是 b1 、b2 ... bm;由於習慣了微信支付,團隊中每個人身上的現金都有限,分別是 a1 a2 ... an,對了,一起出門的老闆還帶有 S 元的團隊經費,這個經費是每個人都可以使用的那麼考慮以下兩個場景

場景1 團隊成員都很有愛,都願意借錢給其他同事,那麼這時候團隊最多能租到多少房子

function max(Array n, Array m, S) {
    return num
}
複製程式碼

場景2 團隊成員都十分小氣,是不願意借錢給別人的

//請判斷團隊成員是否都能租到房子
function isAll(Array n, Array m, S){
   return bool
}
複製程式碼

做法待商榷

場景1:

function max(Array n, Array m, S) {
  let count = 0
  n.forEach(item => {
    count += item
  })
  count += S
  let num = 0
  let mSort = m.slice().sort((a, b) => {
    return a - b
  })
  mSort.forEach(item => {
    count -= item
    if (count >= 0) num++
  })
  return num
}
複製程式碼

場景2:

function isAll(n, m, S) {
  let bool = null;
  let arr = new Array(n.length);
  const avg = S/n;
  n.forEach((item, index) => {
    arr[index] = item + avg
  });
  let mSort = m.slice().sort((a, b) => {
    return a - b
  });
  let arrSort = arr.slice().sort((a, b) => {
    return a - b
  });
  for(let i = 0, len = arrSort.length; i < len; i++) {
    if (arrSort[i] < mSort[i]) {
      bool = false;
      break;
    }
    bool = true;
  }
  return bool;
}
複製程式碼

12、實現一個函式,輸入70040,返回[70000, 40]

function toCount(num) {
  let arr = num.toString().split('')
  return arr.reduce((pre, next, index, array) => {
    if (next === '0') {
      return pre
    } else {
      let item = parseInt(next) * Math.pow(10, array.length - index - 1)
      pre.push(item)
      return pre
    }
  }, [])
}

//or

function toCount1(num) {
  let arr = num.toString().split('')
  let len = arr.length
  let ret = []
  arr.forEach((item, index) => {
    if (item != 0) {
       ret.push(parseInt(item + '0'.repeat(len - index - 1)))
    }
  })
  return ret
}
console.log(toCount1(60040))
複製程式碼

13、請給Array實現一個方法,去重後返回重複的字元(新陣列)

Array.prototype.extraChar = function () {
  var cacheExtraChar = []
  var that = this
  this.map(function (item) {
    (that.indexOf(item) !== that.lastIndexOf(item)) &&
    cacheExtraChar.indexOf(item) === -1 ? cacheExtraChar.push(item) : -1
  })
  return cacheExtraChar
}
複製程式碼

相關文章