Home > Software engineering >  JavaScript: group objects of array per attribute in one object with a list
JavaScript: group objects of array per attribute in one object with a list

Time:01-22

I am currently working on a project in which I have an array of objects, each with "attribute" and "variation".

I need to group them as one object per attribute having the "attribute" and a list of "variations".

Sample Input:

[
    {
        "attribute": "Pack",
        "variation": "full"
    },
    {
        "attribute": "Size",
        "variation": "M"
    },
    {
        "attribute": "Color",
        "variation": "blue"
    },
    {
        "attribute": "Size",
        "variation": "X"
    },
    {
        "attribute": "Color",
        "variation": "red"
    },
    {
        "attribute": "Pack",
        "variation": "half"
    }
]

Expected Output:

[
    {
        "attribute": "Pack",
        "variations": ["full", "half" ]
    },
    {
        "attribute": "Size",
        "variations": ["M", "X"]
    },
    {
        "attribute": "Color",
        "variations": ["blue", "red"]
    },
]

CodePudding user response:

  • Using Array#reduce, iterate over the array while updating an object accumulator where the attribute is the key and the corresponding object (attribute and variations) is the value. In every iteration, in order to update the variations, you need to check if there's already an existing record for the current attribute in acc with a variations list (you can use optional-chaining) and set a default value of an empty array (you can use nullish-coalescing-operator)
  • Using Object#values, return the list of grouped objects, each with attribute and variations

const arr = [ { "attribute": "Pack", "variation": "full" }, { "attribute": "Size", "variation": "M" }, { "attribute": "Color", "variation": "blue" }, { "attribute": "Size", "variation": "X" }, { "attribute": "Color", "variation": "red" }, { "attribute": "Pack", "variation": "half" } ];

const res = Object.values(
  arr.reduce((acc, { attribute, variation }) => ({
    ...acc,
    [attribute]: { 
      attribute, 
      variations: [...(acc[attribute]?.variations ?? []), variation] 
    }
  }), {})
);

console.log(res);

CodePudding user response:

You can try this:

let inputObjs = [
    {
        "attribute": "Pack",
        "variation": "full"
    },
    {
        "attribute": "Size",
        "variation": "M"
    },
    {
        "attribute": "Color",
        "variation": "blue"
    },
    {
        "attribute": "Size",
        "variation": "X"
    },
    {
        "attribute": "Color",
        "variation": "red"
    },
    {
        "attribute": "Pack",
        "variation": "half"
    }
];

let grouped = [];
let attributeIndex = {};
let groupedIndex = 0;
for(k = 0; k < inputObjs.length;k  ){
    const obj = inputObjs[k];
  const attrKey = `_${obj.attribute}`;
  if(typeof attributeIndex[attrKey] != 'undefined'){
    //console.log(grouped[attributeIndex[attrKey]].variations,grouped[attributeIndex[attrKey]].variations.indexOf(obj.variation),obj.variation);
    if(grouped[attributeIndex[attrKey]].variations.indexOf(obj.variation) == -1){
          grouped[attributeIndex[attrKey]].variations.push(obj.variation);
        }
  }else{
    attributeIndex[attrKey] = groupedIndex;
    grouped[attributeIndex[attrKey]] = {attribute:obj.attribute,variations:[]};
    grouped[attributeIndex[attrKey]].variations.push(obj.variation);
    groupedIndex  = 1;
  }
  //console.log(obj);
}
console.log(grouped);
//console.log(attributeIndex);

  •  Tags:  
  • Related