利用常規算法帶你一步一步解決前端實際業務(附彩蛋)

先簡單聊聊

一提到算法,一些小夥伴們聽着「打腦袋」,一些小夥伴會以爲每天搞什麼排序,二叉樹迭代...有啥意思,工做中用不到。哈哈,「老子」說的好,不是用不到,而是你還沒到那個level。今天主要是聊聊學習簡單的算法在實際工做中的利用,沒有什麼過高深的東西(白嫖怪請走開),只是跟你們分享我當初的思考過程,從最low的代碼一步一步思考,最後到基本還看的過去代碼。文章較長!小妹兒,先上鴛鴦鍋吃起!web

業務場景

添加商品 這個簡常見務場景我相信不少小夥伴們都遇到過,你們都知道(SPU)加上一些屬性才組成(SKU),好比最多見的「門」(彩蛋--其實我是賣門的小二,會有些小夥伴沒有這個生活經驗,哈哈!正好給你們普及一下,畢竟未來都是要買房子裝修的人,若是小夥伴正好遇到選門這方面的問題留言諮詢哈!),門是SPU,門包含了顏色、材質、開口方向等一堆屬性,直接上代碼! 算法

 let directions = ["左鎖內開", "左鎖外開","右邊內開","右鎖外開"] //後面給你們配圖   let colors = ["象牙白", "胡桃木","蘋果木"]   let materials = ["原木", "實木","鈦合金"]  複製代碼

那麼一個門SKU就應該是["左鎖內開","象牙白","實木"]、["右邊內開","胡桃木","實木"]等等...大白話就是須要把上面的屬性挨個組合起來。下面正式開始代碼(每一個後臺返回的數據解構不同,實際代碼會有差別)數組

1. 嵌套循環

這種方式是最容易想到了,就是第一個屬性數組迭代,裏面再放入第二個屬性數組,再放第三個...閉包

let skus = []
  for (let i = 0; i < directions.length; i++) {   for (let j = 0; j < colors.length; j++) {   for (var k = 0; k < materials.length; k++) {   let sku = [];   sku.push(directions[i],colors[j],materials[k]);   skus.push(sku)   }   }   }  複製代碼

個人天啦!O(N^3)的複雜度。哈哈,機智的你是否是早就看出了!難道個人屬性只有3個?不可能啊,好比你選了鈦合金門,還有70料,83料,85料,90料等等,不一樣的料價格不一樣也就是不一樣的SKU啊。因此這個操做確定是不行的。編輯器

2. 兩兩組合

上面的操做當額外增長屬性的時候就不行了,那麼咱們先解決這個問題。咱們採用屬性兩兩組合,也就是先讓directions和colors組合成二維數組返回,再和materials組合。上代碼!函數

 let props = [directions, colors, materials,returns],skus = props[0];   for (var k = 1; k < props.length; k++) {  skus = matching(skus, props[k]);  }  function matching(arr, arr1) {  let sku = []  if (!!arr.length && !!arr1.length) {  for (var i = 0; i < arr.length; i++) {  for (var j = 0; j < arr1.length; j++) {  sku.push(`${arr[i]}-${arr1[j]}`)  }  }  return sku  }  }  複製代碼

結果以下: 再遍歷一次分開就搞定。這種操做從時間複雜度能夠當作O(N^2),彷佛解決了未知屬性集合數量的拼裝,可是始終不夠優雅。咱們繼續往下思考!post

2. 排列組合(遞歸回溯)

原本我打算本身貼代碼,可是前幾天看到一篇博文寫的很好,這裏你們能夠看一下 @晨曦時夢見兮 老師的一篇博文,他寫的已經很是仔細了。https://juejin.im/post/5ee6d9026fb9a047e60815f1。 若是晨曦的代碼看着暈能夠看下面每一行加註釋的代碼。學習

這裏我把思路再整理一下:最終咱們須要拼裝成二維數組[["左鎖內開","象牙白","實木"]、["右邊內開","胡桃木","實木"]...],那麼咱們的遞歸體就是去完成二維數組裏面的每一項的拼裝。 爲了方便你們讀我把每一行代碼加了註釋。你們在看代碼的時候,不要硬看,要學會使用debug,同時也要有良好的js基礎,高階函數、閉包、遞歸等等。flex

function createGoods(...goodsProps){
 // goodsProps 爲 已經選擇好的屬性數組  let results = [] //輸出的二維數組  function helper(goodsPropsIndex,prevArr){ //定義遞歸處理函數  //拿到當前迭代的哪個屬性數組,默認傳遞的0,拿第一個屬性數組  let props = goodsProps[goodsPropsIndex]  //獲取是否是最後一組屬性,遞歸的結束條件。  let isLast = goodsPropsIndex == goodsProps.length - 1  for(let prop of props){ //遍歷其中某一個屬性數組  //把當前迭代的屬性數組中取一個與上次傳入的合併。   let cur = prevArr.concat(prop)  //判斷是否是最後一個迭代的屬性數組  if (isLast) {  //若是是,就把合併好的一次放入輸出數組中  results.push(cur)  }else{  //若是不是,就繼續遞歸下一個屬性數組  helper(goodsPropsIndex+1,cur)  }  }  }  helper(0,[]) //參數一爲屬性數組的索引,[]爲拼裝當前此次合併數組  return results  }  複製代碼

總結

你們都是從小白慢慢的學習到能獨擋一面的,只有很是厲害的人才能一下想到 遞歸回溯,借用 晨曦老師的話:咱們能夠先記住一些固定的模式,再從實際工做中去慢慢領會,同時夯實JS基礎,多去嘗試,萌新終究會變成別人眼中的大佬!再次感謝 @晨曦時夢見兮 老師的博文,幫我省了不少篇幅。spa

附錄

如今主流的家裝門是實木貼面,也就是使用實木條加上門皮拼裝的,實木條的多少決定了門的質量和強度,千萬不要相信銷售給你看的小樣,在挑選的要從門的中間網上一掌的位置,從左到右敲,若是聲音基本一致,那就比較厚道的。同時西南地區市場價包安裝大概在1400左右,過低的標註爲實木門的就不要買了。

本文使用 mdnice 排版

相關文章
相關標籤/搜索