I'm struggling to properly convert object into a grouped array of objects. Any suggestions how to get the expected results? The most important part is to group it by HIGH_PRICE
and LOW_PRICE
and create arrays of those grouped keys and values but it would be nice to additionally include name from what's left from similar part of the key for example if I have HIGH_PRICE_QQQ
and LOW_PRICE_QQQ
the name would be QQQ
.
Example of the object to sort:
const obj = {
HIGH_PRICE_QQQ: "10000",
HIGH_PRICE_WWW: "2000",
LOW_PRICE_WWW: "200",
HIGH_PRICE_EEE: "3000",
LOW_PRICE_EEE: "300",
}
Expected result:
const sorted = [
{
name: "QQQ",
HIGH_PRICE_QQQ: "10000",
},
{
name: "WWW",
HIGH_PRICE_WWW: "2000",
LOW_PRICE_WWW: "200",
},
{
name: "EEE",
HIGH_PRICE_EEE: "3000",
LOW_PRICE_EEE: "300",
}
]
CodePudding user response:
you can use reduce
to group by the name. Finally to get the array format as you wanted use Object.values
on the result.
Object.entries
used to make obj
iterable
split
and pop
used to extract the name which is last element of splitted array
const obj = {
HIGH_PRICE_QQQ: "10000",
HIGH_PRICE_WWW: "2000",
LOW_PRICE_WWW: "200",
HIGH_PRICE_EEE: "3000",
LOW_PRICE_EEE: "300",
}
let x = Object.values(Object.entries(obj).reduce((acc,[k,v])=> {
let name = k.split("_").pop()
acc[name]= acc[name] || {name}
acc[name][k] = v
return acc
},{}))
console.log(x)
CodePudding user response:
The below may be one possible solution to achieve the desired objective.
Code Snippet
// helper method to extract the "name"
const getName = s => (
s.includes("HIGH_PRICE_")
? s.split("HIGH_PRICE_").at(1)
: s.includes("LOW_PRICE_")
? s.split("LOW_PRICE_").at(1)
: s
);
// group the object by name
const groupByName = obj => (
Object.values( // extract only values of below result
Object.entries(obj) // extract key-value pairs from argument "obj"
.reduce( // iterate over key-values to generate intermediate result
(fin, [k, v]) => ({ // "fin" is the accumulator / aggregator
...fin,
[getName(k)]: ( // "name" is used as the key, and value is constructed
[getName(k)] in fin
? {...fin[getName(k)], [k]: v}
: { name: getName(k), [k]: v}
)
}),
{} // "fin" is being set to empty-object at begining
)
)
);
const rawObj = {
HIGH_PRICE_QQQ: "10000",
HIGH_PRICE_WWW: "2000",
LOW_PRICE_WWW: "200",
HIGH_PRICE_EEE: "3000",
LOW_PRICE_EEE: "300",
};
console.log(groupByName(rawObj));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Explanation
Inline comments in the above snippet provide description of the various steps.