淘寶sku算法淺析

????????最近項目遇到了一個難題,就是模仿淘寶上的選擇規(guī)格,首先我先來解釋下什么是sku,sku(Stock Keeping Unit 庫存量單位)即庫存進出計量的基本單元,可以是以件,盒,托盤等為單位。sku這是對于大型連鎖超市DC(配送中心)物流管理的一個必要的方法。上面的話可能你們沒有聽懂是什么意思,具體請打開手淘,選擇服裝類的產品(由于服裝類的產品可選規(guī)格較多,比較容易進行比較)。
????????當時項目開始并不是采用這個sku算法,而是采用遍歷查詢的方式,將所有結果進行拆分,拆分成幾個不同屬性的集合;例如顏色、內存、大小等;然后通過用戶點擊按鈕,去遍歷后臺有無包括這種規(guī)格的商品(除了庫存為0);如果沒有則把按鈕變成灰色(即改變狀態(tài));讓我們來分析下這種方案的優(yōu)缺點。

尺寸:5.0寸、4.5寸
型號:土豪金、紅、黑
內存:128G、64G

image.png

后臺可選的規(guī)格:

[
    ["4.5寸", "紅", "64G"],
    ["5.0寸", "土豪金", "128G"],    // 
    ["5.0寸", "黑", "128G"]
]

????????現(xiàn)在這幾種類型一共有2 * 3 * 2 = 12種排列組合,然而只有3種組合是正確的(其中還要排除庫存為0的情況)一開始先保存好每一個按鈕和每一列的位置進入一個List<List<TagEnable>> 的數組中,TagEnable記錄著每一個按鈕的狀態(tài)(0代表者正常,1代表選中,2代表不可選(庫存為0||無規(guī)格));然后當用戶點擊的時候,用Map<Integer,String> 記錄選中的按鈕和文字;并把每一個按鈕先設置為不可點擊,之后根據文字去對按鈕進行設置狀態(tài)。
????????這種算法是比較直接的一種實現(xiàn),但是很繁瑣,循環(huán)嵌套循環(huán),可以簡單分析下算法復雜度,如果sku屬性組合元素的總和數用m來表示,可選的數據的長度是n的話,那么算法的步驟大概是m*n,這看起來好像不怎么復雜;不過,每次判斷一個sku組合是否和result中的 組合匹配,卻不是一個簡單的過程,實際上,這可以看做是一個字符串匹配的一個算法了, 最簡單的還是使用正則匹配,m * n次正則匹配,這樣就不怎么快了吧。正則表達式很不穩(wěn)定,萬一sku組合中有一些特殊字符,就可能導致一個正則匹配沒能匹配到我們想要的表達式。
而且,當用戶全部選中的時候,根據這種算法,只會出現(xiàn)一種情況,就是未選中的全部都變成不可選(即變成灰色),這大大影響了用戶的體驗。如下圖:

第一種方案

????????sku算法是利用數學的集合思想來寫的。即先把可能的排列組合列出來,即取出集合中的所有子集,數學上叫做冪集。
就是如果第一條數據["5.0寸", "黑", "128G"]可選,
那么以下的組合肯定存在:

  • 5.0寸
  • 128G
  • 5.0寸、黑
  • 5.0寸、128G
  • 黑、128G
  • 5.0寸、黑、128G
    所以,我們可以利用sku算法取出所有的組合,再根據這些組合的集合,記為U,去判斷用戶點擊按鈕時,去設置其他按鈕的狀態(tài);
    集合U.png

例如:當用戶進行如下的選擇:5.0寸、128G
那么如何判斷 4.5寸這個按鈕的狀態(tài)呢?只需判斷4.5寸、128G是否可選(集合U是否存在(4.5寸-128G)這個組合并且?guī)齑娌粸?),以此類推:

4.5寸:   U是否包含于 4.5寸-128G   false
土豪金:  U是否包含于 5.0寸-土豪金-128G  true
紅:     U是否包含于 5.0寸-紅-128G  false
黑:     U是否包含于 5.0寸-黑-128G   true
64G:    U是否包含于 5.0寸-64G    false

于是乎,我們可以得出下列的結果:


圖3.png

優(yōu)化:

在使用淘寶的過程中,我發(fā)現(xiàn)他們可以根據用戶選擇按鈕的唯一值確定圖像(例如在這案例中,顏色是唯一的),當用戶只選擇唯一值時,便可以確定其圖像


圖4.png
   StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < mUiData.getAdapters().size(); i++) {
                if (mUiData.getAdapters().get(i).getCurrentSelectedItem()!=null)
                    stringBuilder.append(mUiData.getAdapters().get(i)
                            .getCurrentSelectedItem().getAttributeMemberId()+";");
            }
            if (stringBuilder.length()!=0) {
                List<String> pricelist = new ArrayList<String>();
                for (Map.Entry<String, BaseSkuModel> entry : mUiData.getResult().entrySet()) {
//                            System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
                    if (mUiData.getSelectedEntities().size() == 1) {
                        if (entry.getKey().contains(stringBuilder.toString())) {
                            pricelist.add(entry.getValue().getPicture());
                        }
                    } else {
                        if (entry.getKey().contains(stringBuilder.substring(0, stringBuilder.length() - 1).toString())) {
                            pricelist.add(entry.getValue().getPicture());
                        }
                    }
                }
                List<String> newlist = ifRepeat(pricelist);
                BaseSkuModel baseSkuModel = new BaseSkuModel();
                if (newlist.size() == 1) {
//                Toast.makeText(MainActivity.this,""+,Toast.LENGTH_SHORT).show();
                    baseSkuModel.setPicture(newlist.get(0));
                    baseSkuModel.setPrice(mUiData.getBaseSkuModel().getPrice());
                    baseSkuModel.setFormatNum(mUiData.getBaseSkuModel().getFormatNum());
                    baseSkuModel.setStock(mUiData.getBaseSkuModel().getStock());
                } else {
                    baseSkuModel = mUiData.getBaseSkuModel();
                }
                mUiData.setCurrentskumodel(baseSkuModel);
            }else{
                mUiData.setCurrentskumodel(mUiData.getBaseSkuModel());
            }

做法是這樣子的:先遍歷原始數據,如果用戶選擇的組合在原數據中是唯一的話,則可以確定其圖像。

最后附上github下載地址:

https://github.com/hfkai/SkuSelects

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容