0

It is possible? So this is an extract of the graph:

 [
      {
        "colorName": "yellow",
        "slug": "yellow",
        "colourDescription": "",
        "colourHex": {
          "hex": "#BF0000"
        },
        "colourSerie": "XX1",
        "id": "48361636",
        "secondaryColour": "hsla(0, 100.00%, 12.91%, 1.00)",
        "relatedModels": [
          {
            "id": "48355531",
            "modelName": "modelOne"
          },
          {
            "id": "48355536",
            "modelName": "modelTwo"
          }
        ]
      },
      {
        "colorName": "green",
        "slug": "green",
        "colourDescription": "",
        "colourHex": {
          "hex": "#C3E300"
        },
        "colourSerie": "XX2",
        "id": "58375424",
        "secondaryColour": "hsla(68.45814977973569, 100.00%, 14.24%, 1.00)",
        "relatedModels": [
          {
            "id": "48355512",
            "modelName": "modelFour"
          },
          {
            "id": "48354230",
            "modelName": "modelOne"
          },
          {
            "id": "48355529",
            "modelName": "modelThree"
          }
        ]
      },
      {
        "colorName": "yellow",
        "slug": "yellow",
        "colourDescription": "",
        "colourHex": {
          "hex": "#BF0000"
        },
        "colourSerie": "XX1",
        "id": "48361636",
        "secondaryColour": "hsla(0, 100.00%, 12.91%, 1.00)",
        "relatedModels": [
          {
            "id": "48355531",
            "modelName": "modelOne"
          },
          {
            "id": "48355536",
            "modelName": "modelTwo"
          }
        ]
      },
      ...
    ]

So inside the graph I have several colours that have the same name "colorName". However they are slightly different in the hex. So what I want to achieve is, filter the graph and find the repeated ones, keep the name but mix the property "relatedModels", so if in the original query I have:

colorName: "yellow"
relatedModels: [{modelName:"modelOne"} , {modelName: "modelTwo"}]

colorName: "yellow"
relatedModels: [{modelName:"modelThree"} , {modelName: "modelFour"}]

colorName: "blue"
relatedModels: [{modelName:"modelOne"} , {modelName: "modelTwo"}]

At the end I will have:

colorName: "yellow"
relatedModels: [{modelName:"modelOne"} , {modelName: "modelTwo"}, {modelName: "modelThree"}, {modelName: "modelFour"}]

colorName: "blue"
relatedModels: [{modelName:"modelOne"} , {modelName: "modelTwo"}]

I'm not sure if this is even possible, or at least in one round, the other thing I was thinking to achieve this, is to make 2 different arrays, extract the non unique values, and the unique ones in 2 different objects, and then somehow manipulate the unique ones to mix them(exactly no idea of this part), and combine again the result with the others, however I don't know if is possible, looking at examples to get unique and non unique values, is everything related to arrays, and getting only the value of the property itself but not with object and its values.

What could do was, in the vuex mutation, once I get the array of colours, is too return the unique values, but this what is doing is if it finds 2 modelName with the same value, just take the last one and ignore the next, however this is not what i want but mix both values.

        retrieveColours(state) {
            ...
            const key = 'colorName';
            state.uniqueColours = [...new Map(state.colours.map(item =>
                [item[key], item])).values()]; //return unique value and its values
        },

Thank you in advance for any help, also other suggestions are very welcome.

druj_nasu
  • 131
  • 8
  • 1
    This is just a `group-by` operation. see: [How to group an array of objects by key](https://stackoverflow.com/questions/40774697/how-to-group-an-array-of-objects-by-key) or [Most efficient method to groupby on an array of objects](https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects) – pilchard Dec 13 '21 at 09:50

1 Answers1

0

You could acheive that result with the following:

const result = data.reduce((accu, current) => {

 const obj = accu.find(o => o.colorName === current.colorName)
 if (obj) {
   /* 
    If there is already an object with the same 'colorName' then loop 
    through the 'current.relatedModels' array and add the unique models 
    to this object's 'relatedModels' array.
   */

    for (let model of current.relatedModels) {
      if (!obj.relatedModels.some(m => m.modelName === model.modelName)) {
        obj.relatedModels.push({ ...model })
      }
    }

  } else {
    const {relatedModels, ...rest} = current
    accu.push({ ...rest, relatedModels: relatedModels.map(m => {return {...m}}) })
  }

  return accu
}, [])

Example:

const data = [
  {
    colorName: 'yellow', "slug": "yellow", "colourDescription": "", "colourHex": { "hex": "#BF0000" }, "colourSerie": "XX1", "id": "48361636", "secondaryColour": "hsla(0, 100.00%, 12.91%, 1.00)",
    relatedModels: [
      { id: '48355531', modelName: 'modelOne' },
      { id: '48355536', modelName: 'modelTwo' },
    ]
  },
  {
    colorName: 'green', "slug": "green", "colourDescription": "", "colourHex": { "hex": "#C3E300" }, "colourSerie": "XX2", "id": "58375424", "secondaryColour": "hsla(68.45814977973569, 100.00%, 14.24%, 1.00)",
    relatedModels: [
      { id: '48355512', modelName: 'modelFour' },
      { id: '48354230', modelName: 'modelOne' },
      { id: '48355529', modelName: 'modelThree' },
    ]
  },
  {
    colorName: 'yellow', "slug": "yellow", "colourDescription": "", "colourHex": { "hex": "#BF0000" }, "colourSerie": "XX1", "id": "48361636", "secondaryColour": "hsla(0, 100.00%, 12.91%, 1.00)",
    relatedModels: [
      { id: '123123123', modelName: 'modelThree' },
      { id: '91827391827', modelName: 'modelFour' },
    ]
  }
]

const result = data.reduce((accu, current) => {
 const obj = accu.find(o => o.colorName === current.colorName)
 if (obj) {
    for (let model of current.relatedModels) {
      if (!obj.relatedModels.some(m => m.modelName === model.modelName)) {
        obj.relatedModels.push({ ...model })
      }
    }
  } else {
    const {relatedModels, ...rest} = current
    accu.push({ ...rest, relatedModels: relatedModels.map(m => {return {...m}}) })
  }
  return accu
}, [])

console.log(JSON.stringify(result, null, 2))
.as-console-wrapper { min-height: 100% }

References:
aerial
  • 1,188
  • 3
  • 7
  • 15
  • will take this as an answer, however the first comment is a interesting approach, however due I want this array to be filter in a search functionality that I already built, I think this is more reasonable, because it keeps more or less the structure, so this works best for me. Thank you for take the time to add the links at the end, and comment the script, very helpful :) – druj_nasu Dec 13 '21 at 14:50