Минимальные запасы для электронной коммерции — артикул и реализация алгоритма

внешний интерфейс алгоритм JavaScript
Минимальные запасы для электронной коммерции — артикул и реализация алгоритма

晴天.png

Это 113-я оригинальная статья без воды.Если вы хотите получить больше оригинальных статей, выполните поиск в общедоступном аккаунте и подпишитесь на нас~ Эта статья была впервые опубликована в блоге Zhengcaiyun:Минимальные запасы для электронной коммерции — артикул и реализация алгоритма

предисловие

В текущем бизнесе платформ электронной коммерции, пока есть товары, неизбежно столкновениеSKUФункция аспекта. В этой статье идет переход от теории к практике, от создания продукта к его покупке, и вы узнаете, как реализовать «основной алгоритм», связанный с SKU.

Давайте посмотрим реальный сценарий:

С предварительной обработкой, выбранной в приведенных выше спецификациях, это может помочь пользователям интуитивно понять, можно ли приобрести продукт при покупке продукта.

В нашем фактическом процессе разработки страница создания продукта сначала выполнит сборку спецификации, а страница покупки продукта обработает выбор спецификации. Сборка спецификаций объединяет спецификации в наборы SKU. Выбор спецификации позволяет получить данные запасов в соответствии с содержанием спецификаций и вычислить, можно ли выбрать SKU. Обе функции незаменимы в процессе электронной коммерции.

Практика сборки SKU

Описание недвижимости

в соответствии сЭнциклопедия БайдуОбъяснение SKU

  • Единица хранения запасов (Stock Keeping Unit) В сетевых розничных магазинах один товар иногда называют SKU и определяют как наименьшую доступную единицу для ведения складского учета.Например, SKU в текстиле обычно представляет размер, цвет, и стиль.

Деловая сцена

  • Если вы работаете с продуктами, связанными с электронной коммерцией, такими как приложения для покупок, веб-сайты и т. д., вы столкнетесь с таким сценарием.Каждый продукт соответствует нескольким спецификациям.Пользователи могут выбрать продукт, который они хотят, в соответствии с комбинацией различных характеристики. . Мы сами часто используем эту особенность в своей жизни.

С приведенным выше описанием давайте свяжем концепцию с фактическими данными, давайте возьмем пример 🌰:

Существующие спецификации

const type = ["男裤", "女裤"]
const color = ["黑色", "白色"]
const size = ["S","L"]

Тогда по существующим спецификациям все SKU можно получить как:

[
  ["男裤", "黑色", "S"],
  ["男裤", "黑色", "L"],
  ["男裤", "白色", "S"],
  ["男裤", "白色", "L"],
  ["女裤", "黑色", "S"],
  ["女裤", "黑色", "L"],
  ["女裤", "白色", "S"],
  ["女裤", "白色", "L"],
]

Как получить вышеуказанный SKU, давайте посмотрим на идею реализации и рассчитаем ее через вышеизложенное 🌰.

Идеи реализации комбинации SKU

Декартово произведение

Сначала давайте посмотрим на описание декартова произведения

  • Декартово произведение означает в математике два [набора]XиYДекартово произведение , также известное как [прямое произведение], выражается какX × Y, первый объектXчлен, а второй объектYодин член всех возможных [упорядоченных пар]
  • Предполагая, что множество A = {a, b} и множество B = {0, 1, 2}, декартово произведение двух множеств равно {(a, 0), (a, 1), (a, 2), (b , 0), ( б, 1), ( б, 2) }

Кажется, что декартово произведение удовлетворяет условиям для комбинированного расчета, поэтому давайте сначала проведем волну мыслительных коллизий, сначала пройдемся по карте и посмотрим, как этого добиться

На приведенной выше карте ума видно, что эта комбинация спецификаций является классической комбинацией перестановок, и каждое значение спецификации комбинируется для получения окончательного SKU.

Итак, давайте перейдем к реализации кода и посмотрим, как код реализует декартово произведение.

код реализации

 /**
 * 笛卡尔积组装
 * @param {Array} list
 * @returns []
 */
function descartes(list) {
  // parent 上一级索引;count 指针计数
  let point = {}; // 准备移动指针
  let result = []; // 准备返回数据
  let pIndex = null; // 准备父级指针
  let tempCount = 0; // 每层指针坐标
  let temp = []; // 组装当个 sku 结果

  // 一:根据参数列生成指针对象
  for (let index in list) {
    if (typeof list[index] === 'object') {
      point[index] = { parent: pIndex, count: 0 };
      pIndex = index;
    }
  }

  // 单维度数据结构直接返回
  if (pIndex === null) {
    return list;
  }

  // 动态生成笛卡尔积
  while (true) {
    // 二:生成结果
    let index;
    for (index in list) {
      tempCount = point[index].count;
      temp.push(list[index][tempCount]);
    }
    // 压入结果数组
    result.push(temp);
    temp = [];

    // 三:检查指针最大值问题,移动指针
    while (true) {
      if (point[index].count + 1 >= list[index].length) {
        point[index].count = 0;
        pIndex = point[index].parent;
        if (pIndex === null) {
          return result;
        }
        // 赋值 parent 进行再次检查
        index = pIndex;
      } else {
        point[index].count++;
        break;
      }
    }
  }
}

Давайте посмотрим на фактический ввод и вывод и результат вызова.

Тогда эта классическая проблема перестановок и комбинаций решается таким образом. Далее давайте посмотрим, как работать с выбором товаров с несколькими спецификациями при закупках товаров.

Разнообразие спецификаций продукта

Просмотрите сценарии использования перед запуском

Эта картина смогла четко показать потребности бизнеса. Из приведенных выше анимаций видно, что каждый раз, когда пользователь выбирает определенную спецификацию, необходимо обработать другие спецификации посредством расчета программы, чтобы предоставить пользователю другие спецификации, которые могут быть выбраны в текущей ситуации.

Итак, давайте взглянем на идею реализации.Во-первых, при инициализации укажите необязательные SKU, удалите спецификации, не включенные в необязательные SKU, и укажите спецификации, которые можно будет выбрать на следующем шаге после удаления. второй щелчок пользователя, обработка возможных выбранных SKU и, наконец, получение выбранного SKU после выбора всех спецификаций.

Реализация идеи мультиспецификационного отбора товара

матрица смежности

Во-первых, посмотрите, что такое матрица смежности, отЭнциклопедия Байдуобъяснение

  • Для хранения данных отношения (ребра или дуги) между вершинами используется двумерный массив, который называется матрицей смежности.
  • Логическая структура разделена на две части: множества V и E, где V — вершины, а E — ребра. Поэтому используйте одномерный массив для хранения всех данных вершин в графе.

Буквальное описание может быть неясным, поэтому давайте взглянем на картинку, чтобы помочь понять, если две вершины соединены (соединены), то их соответствующие значения индекса равны 1, иначе 0.

Продолжим с предыдущими данными 🌰

Спецификация

const type = ["男裤", "女裤"]
const color = ["黑色", "白色"]
const size = ["S","L"]

Предположим, что инвентарная стоимость общего SKU является следующим примером, его можно выбрать как наличие на складе, и его нельзя выбрать как отсутствие инвентаря определенной спецификации.

[
  ["男裤", "黑色", "S"], // S 无号
  ["男裤", "黑色", "L"],
  ["男裤", "白色", "S"], // S 无号
  ["男裤", "白色", "L"],
  ["女裤", "黑色", "S"], // S 无号
  ["女裤", "黑色", "L"],
  ["女裤", "白色", "S"], // S 无号
  ["女裤", "白色", "L"],
]

Тогда по идее матрицы смежности можно получить результирующий граф:

Как видно из рисунка, можно выбрать каждые две спецификации в SKU, тогда относительное значение флага равно 1, иначе 0. Когда вся спецификация выбрана как 1, может быть выбрана вся ссылка SKU.

Идея есть, но как это реализовать через код, наверное у всех разные способы реализации, поэтому я представлю свой метод реализации: collection.

Вычислительные идеи

собирать

Средняя школа прошла много лет, это неизбежно забыть, вот обзор определения набора через диаграмму иллюстрации набора

Вышеприведенное изображение взято из изображений Baidu.

Думая о наборах, тогда доступна идея расчета.Здесь нам нужно использовать случай равных наборов для обработки расчета SKU и значений спецификации.

Реализовать интеллект-карту

  • Предположим, есть набор A{a, b, c} и другой набор B{a, e}, как быстро определить, является ли B подмножеством A. Более простой способ решить эту проблему — поочередно сравнивать все элементы в B с элементами в A. Для элементов в наборе значение каждого элемента уникально. С помощью этого свойства мы можем преобразовать все буквы в простое число, тогдаМножество A может быть представлено в виде элементов множества(простое число)** product, B Аналогично, если **B является подмножеством A, достаточно разделить B на A, чтобы увидеть, делится ли оно. Если да, это означает, что B является подмножеством A.
  • Тогда по идее матрицы смежности весь SKU будет иметь один集合值, установленное значение соответствует всем задействованным спецификациям乘积Полученный результат заключается в том, что в процессе выбора спецификации каждый раз, когда выполняется выбор, соответствующее значение спецификации обратно делится в соответствии с установленным значением, чтобы определить, является ли оно подмножеством и равно ли оно 1.
  • Теперь по алгоритму умножения, с приведенным выше анализом, мы можем разобраться в процессе алгоритма:
    • Предварительная обработка данных, однозначное соответствие всего содержимого спецификации, подлежащего обработке, уникальному простому числу и преобразование комбинации ITEM в произведение каждого простого числа.
    • Сканировать все ПУНКТЫ в соответствии с ПУНКТАМИ, которые выбрал пользователь, если ПУНКТЫ были выбраны, выйти, если нет, умножить на все выбранные ПУНКТЫ (поскольку невозможно, чтобы два ПУНКТА с одной и той же категорией отображались в одном комбинация, поэтому выбранный ПУНКТ должен удалить ПУНКТ в той же категории, что и текущий ПУНКТ), эта возможность - набор B выше
    • Разделите товар, образованный комбинацией набора B и SKU (эквивалентен набору A выше) по очереди, сравните, если кратно, выход, можно выбрать текущий совпадающий SKU, если совпадения нет до конца, то текущее Matching Артикул выбрать нельзя.

Давайте посмотрим на основной код через идею коллекции.

основной код

Как вычислить простые числа:

/**
 * 准备质数
 * @param {Int} num 质数范围
 * @returns
 */
getPrime: function (num) {
  // 从第一个质数 2 开始
  let i = 2;
  const arr = [];
  /**
   * 检查是否是质数
   * @param {Int} number
   * @returns
   */
  const isPrime = (number) => {
    for (let ii = 2; ii < number / 2; ++ii) {
      if (number % ii === 0) {
        return false;
      }
    }
    return true;
  };
  // 循环判断,质数数量够完成返回
  for (i; arr.length < total; ++i) {
    if (isPrime(i)) {
      arr.push(i);
    }
  }
  // 返回需要的质数
  return arr;
}
// 上述动图入参以及返回结果展示:
// getPrime(500) return==> 
// 0: (8) [2, 3, 5, 7, 11, 13, 17, 19]
// 1: (8) [23, 29, 31, 37, 41, 43, 47, 53]
// 2: (8) [59, 61, 67, 71, 73, 79, 83, 89]
// 3: (8) [97, 101, 103, 107, 109, 113, 127, 131]
// 4: (8) [137, 139, 149, 151, 157, 163, 167, 173]
// 5: (8) [179, 181, 191, 193, 197, 199, 211, 223]
// 6: (8) [227, 229, 233, 239, 241, 251, 257, 263]

Инициализируйте процесс, чтобы получить первую партию результатов матрицы смежности:

/**
 * 初始化,格式需要对比数据,并进行初始化是否可选计算
 */
init: function () {
  this.light = util.cloneTwo(this.maps, true);
  var light = this.light;

  // 默认每个规则都可以选中,即赋值为 1
  for (var i = 0; i < light.length; i++) {
    var l = light[i];
    for (var j = 0; j < l.length; j++) {
      this._way[l[j]] = [i, j];
      l[j] = 1;
    }
  }
  // 对应结果值,此处将数据处理的方法对应邻接矩阵的思维导图
  // 0: (8) [1, 1, 1, 1, 1, 1, 1, 1]
  // 1: (8) [1, 1, 1, 1, 1, 1, 1, 1]
  // 2: (8) [1, 1, 1, 1, 1, 1, 1, 1]
  // 3: (8) [1, 1, 1, 1, 1, 1, 1, 1]
  // 4: (8) [1, 1, 1, 1, 1, 1, 1, 1]
  // 5: (8) [1, 1, 1, 1, 1, 1, 1, 1]
  // 6: (8) [1, 1, 1, 1, 1, 1, 1, 1]

  // 得到每个可操作的 SKU 质数的集合
  for (i = 0; i < this.openway.length; i++) {
    // 计算结果单行示例:
    // this.openway[i].join('*') ==> eval(2*3*5*7*11*13*17*19)
    this.openway[i] = eval(this.openway[i].join('*'));
  }
  // return 初始化得到规格位置,规格默认可选处理,可选 SKU 的规格对应的质数合集
  this._check();
}

Рассчитать, если необязательный метод:

/**
 * 检查是否可以选择,更新邻接矩阵对应结果值
 * @param {Boolean} isAdd 是否新增状态
 * @returns
 */
_check: function (isAdd) {
  var light = this.light;
  var maps = this.maps;
  
  for (var i = 0; i < light.length; i++) {
    var li = light[i];
    var selected = this._getSelected(i);
    for (var j = 0; j < li.length; j++) {
      if (li[j] !== 2) {
      //如果是加一个条件,只在是 light 值为 1 的点进行选择
        if (isAdd) {
          if (li[j]) {
            light[i][j] = this._checkItem(maps[i][j], selected);
          }
        } else {
          light[i][j] = this._checkItem(maps[i][j], selected);
        }
      }
    }
  }
  return this.light;
},

/**
 * 检查是否可选内容,更新邻接矩阵对应结果值
 * @param {Int} item 当前规格质数
 * @param {Array} selected
 * @returns
 */
_checkItem: function (item, selected) {
  // 拿到可以选择的 SKU 内容集合
  var openway = this.openway;
  var val;
  // 拿到已经选中规格集合*此规格集合值
  val = item * selected;
  // 可选 SKU 集合反除,查询是否可选
  for (var i = 0; i < openway.length; i++) {
    this.count++;
    if (openway[i] % val === 0) {
      return 1;
    }
  }
  return 0;
}

Добавить метод спецификации:

/** 选择可选规格后处理
 * @param {array} point [x, y]
 */
add: function (point) {
  point = point instanceof Array ? point : this._way[point];
  // 得到选中规格对应的质数内容
  var val = this.maps[point[0]][point[1]];

  // 检查是否可选中
  if (!this.light[point[0]][point[1]]) {
    throw new Error(
      'this point [' + point + '] is no availabe, place choose an other'
    );
  }
  // 判断是否选中内容已经存在已经选择内容中
  if (val in this.selected) return;
  
  var isAdd = this._dealChange(point, val);
  this.selected.push(val);
  // 选择后邻接矩阵对应数据修改为 2,以做是否可选区分
  this.light[point[0]][point[1]] = 2;
  this._check(!isAdd);
}

Удалить выбранный метод спецификации:

/**
 * 移除已选规格
 * @param {Array} point 
 */
remove: function (point) {
  point = point instanceof Array ? point : this._way[point];
  // 容错处理
  try {
    var val = this.maps[point[0]][point[1]];
  } catch (e) {}

  if (val) {
    // 在选中内容中,定位取出需要移除规格质数
    for (var i = 0; i < this.selected.length; i++) {
      if (this.selected[i] == val) {
        var line = this._way[this.selected[i]];
        // 对应邻接矩阵内容更新为可选
        this.light[line[0]][line[1]] = 1;
        // 从已选内容中移除
        this.selected.splice(i, 1);
      }
    }
  // 进行重新计算
  this._check();
  }
} 

общий код

Открытый исходный код будет доступен в середине сентября. При необходимости обратите внимание на общедоступную учетную запись WeChat: Zhengcai Cloud Front-end Team. Ответьте на sku, чтобы получить адрес с открытым исходным кодом.

Суммировать

Кажется, учительница нам не врала, что мы узнали на урокеКлассические перестановки,матрица смежности,собиратьЕще очень полезно. Среди классических перестановок и комбинацийДекартово произведениеИдею не нужно заучивать наизусть, но большое количество случаев рекурсивных древовидных диаграмм можно выполнить путем понимания. В соответствии с матрицей смежности сложность пространства может быть упрощена, а оценка данных выбора может быть реализована с помощью идеи агрегации.

Я полагаю, что после прочтения этой статьи у вас появилось общее представление о двух алгоритмах обработки спецификаций электронной коммерции.

использованная литература

1. Вышеупомянутые идеи коллективных вычислений взяты из литературы, подробнее см.Ссылка на сайт.

2. Еще один вид регулярного сопоставления для реализации идеи ссылки на литературу, подробнее см.Ссылка на сайт.

3. Идея матрицы смежности опирается на литературу Подробнее см.Ссылка на сайт.

Рекомендуемое чтение

Что нужно знать об управлении проектами

Самая знакомая незнакомка rc-форма

Как создать платформу сборки и развертывания, подходящую для вашей команды

Поговорим о Дено.

работы с открытым исходным кодом

  • Zhengcaiyun интерфейсный таблоид

адрес с открытым исходным кодомwww.zoo.team/openweekly/(На главной странице официального сайта таблоида есть группа обмена WeChat)

Карьера

ZooTeam, молодая, увлеченная и творческая команда, связанная с отделом исследований и разработок продукции Zhengcaiyun, базируется в живописном Ханчжоу. В настоящее время в команде более 50 фронтенд-партнеров, средний возраст которых составляет 27 лет, и почти 30% из них — инженеры с полным стеком, настоящая молодежная штурмовая группа. В состав членов входят «ветераны» солдат из Ali и NetEase, а также первокурсники из Чжэцзянского университета, Университета науки и технологий Китая, Университета Хандянь и других школ. В дополнение к ежедневным деловым связям, команда также проводит технические исследования и фактические боевые действия в области системы материалов, инженерной платформы, строительной платформы, производительности, облачных приложений, анализа и визуализации данных, а также продвигает и внедряет ряд внутренних технологий. Откройте для себя новые горизонты передовых технологических систем.

Если вы хотите измениться, вас забросали вещами, и вы надеетесь начать их бросать; если вы хотите измениться, вам сказали, что вам нужно больше идей, но вы не можете сломать игру; если вы хотите изменить , у вас есть возможность добиться этого результата, но вы не нужны; если вы хотите изменить то, чего хотите достичь, вам нужна команда для поддержки, но вам некуда вести людей; если вы хотите изменить установившийся ритм, это будет "5 лет рабочего времени и 3 года опыта работы"; если вы хотите изменить исходный Понимание хорошее, но всегда есть размытие того слоя оконной бумаги.. , Если вы верите в силу веры, верьте, что обычные люди могут достичь необыкновенных вещей, и верьте, что они могут встретить лучшего себя. Если вы хотите участвовать в процессе становления бизнеса и лично способствовать росту фронтенд-команды с глубоким пониманием бизнеса, надежной технической системой, технологиями, создающими ценность, и побочным влиянием, я думаю, что мы должны говорить. В любое время, ожидая, пока вы что-нибудь напишете, отправьте это наZooTeam@cai-inc.com