Как массово генерировать уникальные идентификаторы на основе данных JSON?

У меня есть данные как таковые:

const data = [
    {
        "category": "food",
        "brand": "McDonalds",
         "name": "McSpicy",
    },
    {
        "category": "food",
        "brand": "McDonalds",
         "name": "Double Cheese",
    },
    {
        "category": "drink",
        "brand": "Coca-cola",
         "name": "Coke",
    },
    {
        "category": "drink",
        "brand": "Sprite",
         "name": "Sprite",
    },
    {
        "category": "drink",
        "brand": "Coca-cola",
         "name": "Pepsi",
    },
    {
        "category": "food",
        "brand": "KFC",
         "name": "Fried Chicken",
    },
]

Поэтому я хочу сгенерировать идентификаторы для каждого из них в формате ${categoryId} + ${brand} + ${index}, чтобы приведенные выше данные имели идентификаторы как таковые:

0001MCDO0001,
0001MCDO0002,
0002COCA0001,
0002SPRI0001,
0002COCA0002,
0001XKFC0001,

Первые 4 цифры — это идентификатор категории, в этом примере food имеет идентификатор 1, а drink имеет идентификатор 2. Вторые 4 цифры — это первые 4 буквы названия бренда в верхнем регистре, а последние 4 цифры — просто увеличение.

Пока я могу получить первые 8 цифр, но я немного смущен тем, как я могу сгенерировать последние 4 цифры (приращение). Что у меня есть:

const formatId = (newProduct) => {
    let formatted = undefined;
    const category = categoryProduct.find(
      (category) =>
        category.name.replaceAll(" ", "").toLowerCase() ===
        newProduct.category.replaceAll(" ", "").toLowerCase()
    );

    const brandId = (
      "XXX" + newProduct.brand.replaceAll(" ", "").slice(0, 4).toUpperCase()
    ).slice(-4);

    const categoryId = ("000" + category.id).slice(-4);

    const duplicateLen = products.filter(
      (obj) => obj.category === newProduct.category && obj.brand === newProduct.brand
    ).length;

    if (duplicateLen === 0) {
      formatted = categoryId + brandId + "0001";
    } else {
      formatted =
        categoryId +
        brandId +
        ("000" + (duplicateLen + 1)).slice(-4);
    }

    return formatted;
  };

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

Дополнительная информация

categoryProduct в основном представляет собой массив объектов как таковых:

const categoryProducts = [
    {
        id: 1,
        name: "food",
    },
    {
        id: 2,
        name: "drink",
    },
]

и products в основном data, которые я указал выше.

Таким образом, в основном идея состоит в том, чтобы сначала проверить в products / data, есть ли товары с похожей категорией и брендом. Затем мы хотим проверить новые объемные данные, если также есть дубликаты (часть, где я запутался). Затем сделайте приращение соответственно.

Как я применяю функцию, так это:

data.forEach((obj) => {
   obj.id = formatId(obj);

   for (var i in obj) {
       if (obj[i] === undefined) {
           obj[i] = "";
   }
}
});

Что такое jenisId? Пожалуйста, создайте полный фрагмент со всем кодом.

Simone Rossaini 21.02.2023 08:25

«последние 4 цифры просто увеличиваются» ... из какой базы? Они, кажется, сбрасываются для каждой категории по мере их появления.

Phil 21.02.2023 08:42

«Я немного застрял в том, как я могу реализовать это, когда пытаюсь добавить несколько продуктов одновременно». И причина, по которой вы не можете просто использовать for или foreach для циклического прохождения, заключается в...? С какой проблемой вы на самом деле сталкиваетесь, когда кодируете это?

TylerH 21.02.2023 15:48
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вместо использования products для повторяющегося значения я использовал окончательный массив с filter, например:

const products = [{
    "category": "food",
    "brand": "McDonalds",
    "name": "McSpicy",
  },
  {
    "category": "food",
    "brand": "McDonalds",
    "name": "Double Cheese",
  },
  {
    "category": "drink",
    "brand": "Coca-cola",
    "name": "Coke",
  },
  {
    "category": "drink",
    "brand": "Sprite",
    "name": "Sprite",
  },
  {
    "category": "drink",
    "brand": "Coca-cola",
    "name": "Pepsi",
  },
  {
    "category": "food",
    "brand": "KFC",
    "name": "Fried Chicken",
  },
];
const categoryProduct = [{
    id: 1,
    name: "food",
    counter: 1,
  },
  {
    id: 2,
    name: "drink",
    counter: 1,
  },
];
const formatId = (newProduct) => {
  let formatted = undefined;
  const category = categoryProduct.find(
    (category) =>
    category.name.replaceAll(" ", "").toLowerCase() ===
    newProduct.category.replaceAll(" ", "").toLowerCase()
  );

  const brandId = (
    "XXX" + newProduct.brand.replaceAll(" ", "").slice(0, 4).toUpperCase()
  ).slice(-4);

  const categoryId = ("000" + category.id).slice(-4);

  const duplicateLen = final.filter(el =>  el.substring(0,8) === categoryId + brandId).length;
  
  if (duplicateLen === 0) {
    formatted = categoryId + brandId + "0001";
  } else {
    formatted =
      categoryId +
      brandId +
      ("000" + (duplicateLen + 1)).slice(-4);
  }

  return formatted;
};
const final = [];
products.forEach(el => {
  final.push(formatId(el));
});
console.info(final);
  1. Создавайте индексированные структуры данных для более быстрого поиска таких вещей, как идентификатор категории.
  2. Создайте вспомогательные функции для каждого раздела ID
  3. Сопоставьте исходный массив, чтобы создать новый с добавленными идентификаторами.
  4. Отслеживайте комбинацию категории и бренда в другой структуре данных, чтобы знать, когда увеличивать индекс.

const data = [{"category":"food","brand":"McDonalds","name":"McSpicy"},{"category":"food","brand":"McDonalds","name":"Double Cheese"},{"category":"drink","brand":"Coca-cola","name":"Coke"},{"category":"drink","brand":"Sprite","name":"Sprite"},{"category":"drink","brand":"Coca-cola","name":"Pepsi"},{"category":"food","brand":"KFC","name":"Fried Chicken"}];
const categoryProducts = [{"id":1,"name":"food"},{"id":2,"name":"drink"}];

// Index categories
const categoryMap = Object.fromEntries(
  categoryProducts.map(({ id, name }) => [name, id.toString()])
);

// Helpers
const hashCategory = ({ category }) => categoryMap[category].padStart(4, "0");
const hashBrand = ({ brand }) =>
  brand.replace(/\W/g, "").slice(0, 4).toUpperCase().padStart(4, "X");

// Brand / category indexes
const categoryIndex = {};

const newData = data.map((obj) => {
  const key = hashCategory(obj) + hashBrand(obj);
  categoryIndex[key] = (categoryIndex[key] ?? 0) + 1;
  return {
    id: key + categoryIndex[key].toString().padStart(4, "0"),
    ...obj,
  };
});

console.info(newData);
.as-console-wrapper { max-height: 100% !important; }

Возможно, было бы чище использовать заводской шаблон.

const data = [
  {
      "category": "food",
      "brand": "McDonalds",
       "name": "McSpicy",
  },
  {
      "category": "food",
      "brand": "McDonalds",
       "name": "Double Cheese",
  },
  {
      "category": "drink",
      "brand": "Coca-cola",
       "name": "Coke",
  },
  {
      "category": "drink",
      "brand": "Sprite",
       "name": "Sprite",
  },
  {
      "category": "drink",
      "brand": "Coca-cola",
       "name": "Pepsi",
  },
  {
      "category": "food",
      "brand": "KFC",
       "name": "Fried Chicken",
  },
]

class IdFactory {
  _catIdMap = new Map();
  _catId = 0;
  _idxMap = new Map();

  getId(data) {
    const {category, brand, name} = data;
    let catId = this._catIdMap.get(category);

    if (!catId) {
      catId = ++this._catId;
      this._catIdMap.set(category, catId);
    }

    const lpad = (i) => ("0000" + i).slice(-4);

    const brandId = ("XXX" + brand.replaceAll(" ", "").slice(0, 4).toUpperCase()).slice(-4);

    const pfx =  `${lpad(catId)}${brandId}`
    let idx = this._idxMap.get(pfx);
    if (idx) {
      this._idxMap.set(pfx, ++idx);
    } else {
      idx = 1;
      this._idxMap.set(pfx, 1);
    }
    return `${pfx}${lpad(idx)}`;    
  }
}

const f = new IdFactory()
console.info(data.map(d => f.getId(d)));

Другие вопросы по теме