introduce

A seemingly simple sku inside water is very deep, is three times the same question trouble you will want to solution, will meet on the web or mobile end, so have the following sku selected solution thinking source: hooray. Making. IO/posts / 8 b2bd… I had some ideas when I saw the list of all the specifications in this article

The target

  • Pass in the currently selected specifications to determine whether each specification is selectable
  • Passing in the currently selected specification determines which specific SKU is currently selected

Train of thought

Using the skU list, you can get the set of all the states that the user can select, so that the set can be obtained in advance (admittedly, this set can be very large when the size is large, so I choose time for space and time here). When the user selects the size, By going directly to the previous set of maps (where the time cost is, in theory, the same as fetching a key from an object), you can get all the possibilities of the SKU, and thus which specifications are currently available or not

implementation

Product data: SKUS list and specification list

const skuListData = [
  { specIds: ["100"."010"].stock: 12.price: 1.img: "1" },
  { specIds: ["100"."020"].stock: 12.price: 1.img: "1" },
  { specIds: ["200"."020"].stock: 12.price: 1.img: "1"},];const specListData = [
  {
    name: "Level".items: [{name: "Level".id: "100" },
      { name: "Secondary".id: "200"},],}, {name: "Brand".items: [{name: Nongfu Spring.id: "010" },
      { name: "Pan apple".id: "020"},],},];Copy the code

How do I get the set of states that all users can select

It comes from the following two functions

function arrayCombine(targetArr: any) {
  var resultArr = [];
  for (var n = 0; n <= targetArr.length; n++) {
    var flagArrs = getFlagArrs(targetArr.length, n);
    while (flagArrs.length) {
      var flagArr = flagArrs.shift() || [];
      // var combArr = Array(targetArr.length);
      var combArr = [];
      for (var i = 0; i < targetArr.length; i++) {
        if(flagArr[i]) { combArr.push(targetArr[i]); } } resultArr.push(combArr); }}return resultArr;
}
// Take all combinations of n from m
function getFlagArrs(m: any, n: any) {
  var flagArrs = [],
    flagArr = [],
    isEnd = false;
  for (var i = 0; i < m; i++) {
    flagArr[i] = i < n ? 1 : 0;
  }
  flagArrs.push(flagArr.concat());
  // enter when n is not equal to 0 and m is greater than n
  if (n && m > n) {
    while(! isEnd) {var leftCnt = 0;
      for (var i = 0; i < m - 1; i++) {
        if (flagArr[i] === 1 && flagArr[i + 1= = =0) {
          for (var j = 0; j < i; j++) {
            flagArr[j] = j < leftCnt ? 1 : 0;
          }
          flagArr[i] = 0;
          flagArr[i + 1] = 1;
          var aTmp = flagArr.concat();
          flagArrs.push(aTmp);
          if (aTmp.slice(-n).join("").indexOf("0") = = -1) {
            isEnd = true;
          }
          break;
        }
        flagArr[i] == 1&& leftCnt++; }}}return flagArrs;
}
Copy the code

The result of passing the specification of the SKU list into arrayCombine

Explanation: For example, specIds for my first SKU data: [“100”, “010”] This SKU is the combination of two specification ids of 100,010, so all the circumstances in the process of selecting this SKU are the first result of arrayCombine above, namely, do not select, select 100 specification, select 010 specification, Choose 100 and 010 specifications for four cases

When the user selects a specification, he can directly know in advance which SKUs are currently available, so as to determine whether the current specification is available or not

At the end

The above idea is the core idea, specific implementation, such as I know those SKU optional how to judge the specifications optional there is no specific to start talking, if you are interested in continuing to see the move: github.com/winljm001/s…

You can directly import the sku-status-class library written by the author and use the above data to try (the actual use of the data field is not the same as the map of the next time you use it)

Functionally, there is no problem. After thinking, there are also points that can be optimized. After there are bugs or empty, we will continue to iterate and optimize

Usage:

import Sku from "sku-status-class";
const selected = ["100"."010"];
const a = new Sku(skuListData, specListData);
// Get the specification status
console.log(a.getSpecListStatus(selected));
// Get the selected specifications
const a = new Sku(skuListData, specListData);
// console.log(a.getSkuGoods(selected));
Copy the code

The result of the above use will be obtained

With specStatus you can render the status of the current specification on the page as selected, optional, and not optional