-2

I need solution of merging objects using keys.

var data = [
  { FromSize: 54, ToSize: 51, ClearityName: 'IF', Price: 56 },
  { FromSize: 54, ToSize: 51, ClearityName: 'VS', Price: 96 },
  { FromSize: 54, ToSize: 51, ClearityName: 'VSS', Price: 26 },
  { FromSize: 40, ToSize: 30, ClearityName: 'PF', Price: 36 },
  { FromSize: 40, ToSize: 30, ClearityName: 'IF', Price: 86 }
];

Output will be like given bellow

[
  { FromSize: 54, ToSize: 51, IF: 56, VS: 96, VSS: 26 },
  { FromSize: 40, ToSize: 30, PF: 36, IF: 86 }
]
Peter Krebs
  • 3,831
  • 2
  • 15
  • 29
  • 2
    What have you tried so far? – Pilpo Sep 24 '21 at 12:25
  • i have tried by using of grouping but did not worked @Pilpo – Jay Gandhi Sep 24 '21 at 12:27
  • 1
    Please show what you did then and in what way it failed, thank you. – CherryDT Sep 24 '21 at 12:29
  • 1
    My suggestion is to create an object, then iterate over the data, create a key made from a combination of `FromSize` and `ToSize` (e.g. joined by some character) for each record, create an entry in the object for that key if it doesn't yet exist, set the property on the entry based on `ClearityName` and `Price`, and at the end output the `Object.values` of your object. – CherryDT Sep 24 '21 at 12:30
  • i have tried using with the help this [link](https://stackoverflow.com/questions/46794232/group-objects-by-multiple-properties-in-array-then-sum-up-their-values) i am not star of javascript. i have not much experice in javascript. thank you @CherryDT – Jay Gandhi Sep 24 '21 at 12:31
  • 1
    Familiarize yourself with [how to access and process nested objects, arrays or JSON](/q/11922383/4642212) and how to [create objects](//developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Object_initializer) and use the available static and instance methods of [`Object`](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object#Static_methods) and [`Array`](//developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array#Static_methods). – Sebastian Simon Sep 24 '21 at 12:31

1 Answers1

4

My suggestion is to create an object, then iterate over the data, create a key made from a combination of FromSize and ToSize (e.g. joined by some character) for each record, create an entry in the object for that key if it doesn't yet exist, set the property on the entry based on ClearityName and Price, and at the end output the Object.values of your object.


Let's look at it step by step:

First, let's create an object which will temporarily hold our results as mapping from some key to some value:

const groupedData = {}

Then, let's iterate over our data using for of:

for (const record of data) {
  /* ... */
}

We could now access the values using record.FromSize, etc. but the following code will be shorter if we destructure the properties at this point already, because we can take advantage of property shorthands (e.g. we can write { FromSize } instead of { FromSize: record.FromSize }):

for (const { FromSize, ToSize, ClearityName, Price } of data) {
  /* ... */
}

For each record, we'll first build a key string from FromSize and ToSize so we can group by it. Since it's two values, we need to join them somehow. Since both are numbers, it's safe to just join them by a character like a comma so that FromSize: 54, ToSize: 51 will give you 54,51:

const key = `${FromSize},${ToSize}`

Then if we create an entry in our grouped data object for the current key if it doesn't exist already. This entry will contain just the base properties of FromSize and ToSize because the others will be created individually afterwards:

groupedData[key] ??= { FromSize, ToSize }

The ??= operator is relatively new in JavaScript. x ??= y means the same as x = x ?? y, with ?? being the nullish coalescing operator which evaluates to its right-hand-side argument if the left-hand-side argument is null or undefined, otherwise it will evaluate to the left-hand-side argument. Essentially, x ??= y allows us to set x to y if it wasn't already set to something else before (more or less). If this gives you a syntax error, try the more verbose way of if (!groupedData[key]) groupedData[key] = { FromSize, ToSize } instead.

Now that we have ensured that groupedData[key] exists and has at least FromSize and ToSize set, we can set the new property that we need based on the ClearityName, with a value of Price:

groupedData[key][ClearityName] = Price

At this point, after our loop is completed, we have groupedData as object with keys like 54,51 and values like { FromSize: 54, ToSize: 51, IF: 56, VS: 96, VSS: 26 }, but you want an array of those values and are no longer interested in the keys at that point. You can get that using Object.values:

const output = Object.values(groupedData)

Final result:

function getGroupedArray (data) {
  const groupedData = {}
  
  for (const { FromSize, ToSize, ClearityName, Price } of data) {
    const key = `${FromSize},${ToSize}`
    groupedData[key] ??= { FromSize, ToSize }
    groupedData[key][ClearityName] = Price
  }
  
  return Object.values(groupedData)
}

// Let's test it:

const data = [
  { FromSize: 54, ToSize: 51, ClearityName: 'IF', Price: 56 },
  { FromSize: 54, ToSize: 51, ClearityName: 'VS', Price: 96 },
  { FromSize: 54, ToSize: 51, ClearityName: 'VSS', Price: 26 },
  { FromSize: 40, ToSize: 30, ClearityName: 'PF', Price: 36 },
  { FromSize: 40, ToSize: 30, ClearityName: 'IF', Price: 86 },
]

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

Click "Run code snippet" above to see it in action!

(Note: You can ignore the .as-console-wrapper stuff here, that's just so that Stack Overflow will display the output in a nicer way.)

You can find more information about each of the functions used here by googling their names. If you are stuck understanding a certain piece of code I used here, just ask!

CherryDT
  • 25,571
  • 5
  • 49
  • 74