I have a nested json array and I am trying to get the maximum value of the points attribute in this array.
data = {
"name": "KSE100",
"children": [
{
"name": "TECHNOLOGY & COMMUNICATION",
"children": [
{
"name": "TRG",
'points': -21
},
{
"name": "SYS",
},
]
},
{
"name": "OIL",
"children": [
{
"name": "PPL",
'points': 9
},
{
"name": "PSO",
'points': -19
},
]
},
]
}
I want the max value of points from under the children sections. I mean from under technology and oil sectors.
What I've done so far:
var max;
for (var i in data.children.length) {
for (var j in data.data[i]) {
var point = data.data[i].children[j]
}
}
CodePudding user response:
Try the following:
data = {
"name": "KSE100",
"children": [
{
"name": "TECHNOLOGY & COMMUNICATION",
"children": [
{
"name": "TRG",
'points': -21
},
{
"name": "SYS",
},
]
},
{
"name": "OIL",
"children": [
{
"name": "PPL",
'points': 9
},
{
"name": "PSO",
'points': -19
},
]
},
]
}
var array = [];
for (var first of data.children) {
for (var second of first.children) {
if(second.points != undefined)
{
array.push(second);
}
}
}
var maximumValue = Math.max.apply(Math, array.map(function(obj) { return obj.points; }));
console.log(maximumValue);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
you can use the reduce method on the array object to do this
const maxValues = []
data.children.forEach(el => {
if (el.name === 'OIL' || el.name === 'TECHNOLOGY & COMMUNICATIO'){
const max = el.children.reduce((current, previous) => {
if (current.points > previous.points) {
return current
}
}, 0)
maxValues.append({name: el.name, value: max.points})
}
})
This will give you an array of the objects with the name and max value.
CodePudding user response:
First you can convert your object to a string through JSON.stringify
so that you're able to use a regular expression
(?<=\"points\":)-?\\d*
To matchAll
the values preceded by the pattern \"points\":
that are or not negative values. After it, convert the result to a array through the spread operator ...
and then reduce it to get the max value.
const data = {name:"KSE100",children:[{name:"TECHNOLOGY & COMMUNICATION",children:[{name:"TRG",points:-21},{name:"SYS"}]},{name:"OIL",children:[{name:"PPL",points:9},{name:"PSO",points:-19}]}]};
console.log(
[ ...JSON.stringify(data).matchAll('(?<=\"points\":)-?\\d*')]
.reduce((acc, curr) => Math.max(curr, acc))
)
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
I wasn't 100% sure, what your exact goal is, so I included a grouped max value and and overall max value with a slight functional approach.
Please be aware that some functionalities are not working in older browsers i.e. flatMap
. This should anyways help you get started and move on.
const data = {
name: "KSE100",
children: [
{
name: "TECHNOLOGY & COMMUNICATION",
children: [
{
name: "TRG",
points: -21,
},
{
name: "SYS",
},
],
},
{
name: "OIL",
children: [
{
name: "PPL",
points: 9,
},
{
name: "PSO",
points: -19,
},
],
},
],
};
const maxPointsByGroup = data.children.reduce(
(acc, entry) => [
...acc,
{
name: entry.name,
max: Math.max(
...entry.children
.map((entry) => entry.points)
.filter((entry) => typeof entry === "number")
),
},
],
[]
);
console.log("grouped max:", maxPointsByGroup);
const overallMax = Math.max(
...data.children
.flatMap((entry) => entry.children.flatMap((entry) => entry.points))
.filter((entry) => typeof entry === "number")
);
console.log("overall max:", overallMax);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>