Javascript – What is the best way to generate unique ID based on data that has been given?

I have data as such:

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",
    },
]

So I want to generate IDs for each of them in the format of ${categoryId} + ${brand} + ${index} so it would the data above would have IDs as such:

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

The first 4 digits are the category ID, in this example food has the id of 1 and drink has the id of 2. Second 4-digits are the first 4 letters of the brand uppercased and last 4 digits are just increment.

So far I am able to get the first 8 digits, but I’m a little confused on how I can generate the last 4 digits (increment). What I have:

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;
  };

The code above is usable when I’m trying to add 1 product at a time. I am a little stuck on how I can implement this when I’m trying to add multiple products at once (bulk update).

Additional Info

categoryProduct is basically an array of objects as such:

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

and products are basically data which I have stated above.

So basically the idea is to check first in products / data if there are items with similar category and brand. Then we want to check in the new bulk data, if there are duplicates as well (part where I’m confused). Then do increment accordingly.

How I’m applying the function is as such:

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

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

>Solution :

Instead of use products for duplicate value, i used final array with filter like:

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.log(final);

Leave a Reply