Home > Software engineering >  how to get max value from a nested json array
how to get max value from a nested json array

Time:10-17

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>

  • Related