1

I am working in a ReactJS application where I retrieve a JSON with some products, and I need to restructure this information in order to categorize and show the information.

I have already tried with filters and maps, but it didn't turn out as expected.

[
    {
        "barcode": "8434786768366",
        "collection": "AW",
        "colorCode": "413",
        "colorName": "LIGHT WINE",
        "familyCode": "1",
        "familyName": "T-Shirts",
        "genericProduct": "PM506471",
        "id": 263917,
        "productCode": "PM506471413S",
        "productName": "T-SHIRT",
        "productNameLang": "en",
        "season": "2019",
        "size": "S",
        "subfamilyName": "SS T-Shirts"
    },
    {
        "barcode": "8434786768342",
        "collection": "AW",
        "colorCode": "413",
        "colorName": "LIGHT WINE",
        "familyCode": "1",
        "familyName": "T-Shirts",
        "genericProduct": "PM506471",
        "id": 263921,
        "productCode": "PM506471413L",
        "productName": "T-SHIRT",
        "productNameLang": "en",
        "season": "2019",
        "size": "L",
        "subfamilyName": "SS T-Shirts"
    }
]

This is a sample of what im working with, though the original array is much bigger. I need to be able to find all the objects that have the same "genericProduct" and merge them together in a single object, in order to remove duplicates. However, I need to preserve the information instead of overriding it.

Following the example above, those two objects should merge into something like this:

[
    {
        "barcode": ["8434786768366", "8434786768342"],
        "collection": "AW",
        "colorCode": "413",
        "colorName": "LIGHT WINE",
        "familyCode": "1",
        "familyName": "T-Shirts",
        "genericProduct": "PM506471",
        "id": [263917, 263917],
        "productCode": ["PM506471413S","PM506471413L"],
        "productName": "T-SHIRT",
        "productNameLang": "en",
        "season": "2019",
        "size": ["S","L"],
        "subfamilyName": "SS T-Shirts"
    }
]

As a tl;dr I need to iterate in an object array to see which have the same "genericProduct" key, and then check each property to see if it is different. If it is, I need to transform said property into an array that stores all values, being two or more.

1

3 Answers 3

3

Go through the array and for each item declare an empty object. Now check the entire array for duplicates inside this object and merge the repeated property into an array.

const items = [
    {
        "barcode": "8434786768366",
        "collection": "AW",
        "colorCode": "413",
        "colorName": "LIGHT WINE",
        "familyCode": "1",
        "familyName": "T-Shirts",
        "genericProduct": "PM506471",
        "id": 263917,
        "productCode": "PM506471413S",
        "productName": "T-SHIRT",
        "productNameLang": "en",
        "season": "2019",
        "size": "S",
        "subfamilyName": "SS T-Shirts"
    },
    {
        "barcode": "8434786768342",
        "collection": "AW",
        "colorCode": "413",
        "colorName": "LIGHT WINE",
        "familyCode": "1",
        "familyName": "T-Shirts",
        "genericProduct": "PM506471",
        "id": 263921,
        "productCode": "PM506471413L",
        "productName": "T-SHIRT",
        "productNameLang": "en",
        "season": "2019",
        "size": "L",
        "subfamilyName": "SS T-Shirts"
    }
]

const result = []

   const obj = {}
   items.map(item =>{
       Object.keys(item).map(key =>{
           if(obj[key] && obj[key] !== item[key])
               return obj[key] = [obj[key], item[key]].flat()
            return obj[key] = item[key]
       })
   })
 
   result.push(obj)
   

console.log(result)

Sign up to request clarification or add additional context in comments.

5 Comments

Nice use of flat!
Why have the first loop if you never use i?
That it's called distraction. happens a lot
Cool! This isn't the result op asked for though 🤷
Yeap I wasn't checking if the values are equal before merging. if(obj[key] && obj[key] !== item[key]) to solve, edited. Thank you
2

Here you go! I did two assumptions:

  • Keep duplicates of values
  • All objects have the same properties and their values are never objects (like in the example data)

You were probably on the right track looking at the Array methods. Maybe you missed looking at reduce?

const data = [
  {
    barcode: "8434786768366",
    collection: "AW",
    colorCode: "413",
    colorName: "LIGHT WINE",
    familyCode: "1",
    familyName: "T-Shirts",
    genericProduct: "PM506471",
    id: 263917,
    productCode: "PM506471413S",
    productName: "T-SHIRT",
    productNameLang: "en",
    season: "2019",
    size: "S",
    subfamilyName: "SS T-Shirts"
  },
  {
    barcode: "8434786768342",
    collection: "AW",
    colorCode: "413",
    colorName: "LIGHT WINE",
    familyCode: "1",
    familyName: "T-Shirts",
    genericProduct: "PM506471",
    id: 263921,
    productCode: "PM506471413L",
    productName: "T-SHIRT",
    productNameLang: "en",
    season: "2019",
    size: "L",
    subfamilyName: "SS T-Shirts"
  },
  {
    barcode: "8434786768342",
    collection: "AW",
    colorCode: "413",
    colorName: "LIGHT WINE",
    familyCode: "1",
    familyName: "T-Shirts",
    genericProduct: "PM506471",
    id: 263921,
    productCode: "PM506471413L",
    productName: "T-SHIRT",
    productNameLang: "en",
    season: "2019",
    size: "L",
    subfamilyName: "SS T-Shirts"
  }
];

const result = data.reduce((acc, product) => {
  const merged = Object.keys(product)
    .filter(key => acc[key] !== product[key])
    .reduce(
      (mergedObject, key) => ({
        ...mergedObject,
        [key]:
          acc[key] instanceof Array
            ? acc[key].concat([product[key]])
            : [acc[key], product[key]]
      }),
      {}
    );

  return {
    ...acc,
    ...merged
  };
});

console.log(result);

Update simplify and use better variable names

1 Comment

Nice use of reduce.
0

You could get the entries and chck if the property exist or if the value exists or if the value is inside of the array.

Otherwise assign the value or create an array with the former values and the actual value.

var data = [{ barcode: "8434786768366", collection: "AW", colorCode: "413", colorName: "LIGHT WINE", familyCode: "1", familyName: "T-Shirts", genericProduct: "PM506471", id: 263917, productCode: "PM506471413S", productName: "T-SHIRT", productNameLang: "en", season: "2019", size: "S", subfamilyName: "SS T-Shirts" }, { barcode: "8434786768342", collection: "AW", colorCode: "413", colorName: "LIGHT WINE", familyCode: "1", familyName: "T-Shirts", genericProduct: "PM506471", id: 263921, productCode: "PM506471413L", productName: "T-SHIRT", productNameLang: "en", season: "2019", size: "L", subfamilyName: "SS T-Shirts" }],
    result = data.reduce((r, o) => {
        Object.entries(o).forEach(([k, v]) => {
            if (!(k in r)) return r[k] = v;
            if (r[k] === v || Array.isArray(r[k]) && r[k].includes(v)) return;
            r[k] = [].concat(r[k], v);
        });        
        return r;
    }, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.