Search code examples
javascriptarraysgroupingclone

Clone object based on property javascript


I'm getting a group of objects in JSON like so

[ 
    { name: "Doc 1", 
      product: ["product 1", "product 2"],
      type: ["type 1", "type 2"] 
    },
    { name: "Doc 2", 
      product: ["product 1"],
      type: ["type 1"] 
    },
    { name: "Doc 3", 
      product: ["product 2"],
      type: ["type 2"] 
    }
    ...
]

I need to first clone the object for each product of the object (so I'd have 2 instances of Doc 1) and then I want to group the objects based on the product (that would give me another 2 objects) and then grouped based on the type which would give me another 2.

Initially we were just grouping based on the product but we then found our docs had multiple products associated with it and so we need to transform the original.

How would I clone each card to a new array for each product?

It's anticipated that the final group of objects would look like in this simple instance, Doc 1 is the only duplicate as it's associated with product 1 and 2.

[ 
  { name: "Doc 1", 
    product: ["product 1", "product 2"],
    type: ["type 1", "type 2"] 
  },
  { name: "Doc 1", 
    product: ["product 1", "product 2"],
    type: ["type 1", "type 2"] 
  },
  { name: "Doc 2", 
    product: ["product 1"],
    type: ["type 1"] 
  },
  { name: "Doc 3", 
    product: ["product 2"],
    type: ["type 2"] 
  }
  ...
]

Solution

  • You can use Object.assign to clone the object and [].concat(yourArray) to clone an array of primitives.

    var docs = [ 
        { name: "Doc 1", 
          product: ["product 1", "product 2"],
          type: ["type 1", "type 2"] 
        },
        { name: "Doc 2", 
          product: ["product 1"],
          type: ["type 1"] 
        },
        { name: "Doc 3", 
          product: ["product 2"],
          type: ["type 2"] 
        }
    ]
    
    var cloned = docs.map(function (c) {
       // This will not clone the product
       c = Object.assign({}, c);
       
       // Clone the product array
       c.product = [].concat(c.product);
       return c;
    });
    
    // Group by products
    var byProduct = {
      /*
        "product 1": [...]
      */
    };
    
    cloned.forEach(function (c) {
      c.product.forEach(function (prod) {
        var groupedDocs = byProduct[prod] = byProduct[prod] || [];
        groupedDocs.push(c);
      });
    });
    
    console.log(byProduct);