Master Bee
Master Bee

Reputation: 1099

Finding the max value of an attribute in an array of objects in an object

I have a JavaScript object and want to get the highest value of all entries. I have tried this:

d = {
"A": [ {"value": 10}, {"value": 20}, {"value": 30} ],
"B": [ {"value": 50}, {"value": 60}, {"value": 1000} ],
}

Object.keys(d).map(
    function(k) { 
        Math.max.apply(Math, d[k].map(
            function(e) {
                console.log(value);
            }
        ))
    }
) 

The result should be 1000.

Upvotes: 2

Views: 490

Answers (9)

Slai
Slai

Reputation: 22876

For actual JSON string, it can be done during parsing :

var max = -Infinity, json = '{"A":[{"value":10},{"value":20},{"value":30}],"B":[{"value":50},{"value":60},{"value":1000}]}'

JSON.parse(json, (k, v) => max = v > max ? v : max)

console.log( max )

For JavaScript object :

const d = { "A": [ {"value": 10}, {"value": 20}, {"value":   30 } ],
            "B": [ {"value": 50}, {"value": 60}, {"value": 1000 } ] }

console.log( Math.max(...Object.values(d).flat().map(x => x.value)) )

Upvotes: 0

shikhar
shikhar

Reputation: 140

Only simply using map and reduce and chaining them together can give you the desired max value. I have used underscore js though, you can use simple map and reduce methods for the same.

var d = {
     "A": [ {"value": 10}, {"value": 20}, {"value": 30} ],
     "B": [ {"value": 50}, {"value": 60}, {"value": 1000} ],
     "C": [ {"value": 30}, {"value": 90}, {"value": 300} ],
     }

var maxvalue = _.reduce(_.map(d,(items)=>{  
    return _.reduce(items , (p,i)=>{
            return p> i.value ? p: i.value;
        },0)
}) , (maxy, iter)=>{
    return maxy > iter ? maxy: iter;
},0);

Upvotes: 0

Akrion
Akrion

Reputation: 18515

Since neither Array.flat nor Array.flatMap are well supported without polyfill here is a solution with Array.reduce, Object.values and Array.map:

const d = {
"A": [ {"value": 10}, {"value": 20}, {"value": 30} ],
"B": [ {"value": 50}, {"value": 60}, {"value": 1000} ],
}

let r = Math.max(...Object.values(d).reduce((r,c)=>[...r,...c]).map(x => x.value))

console.log(r)

The idea is to use Object.values to get straight to the values of the object. Then use Array.reduce for the flattening of the arrays and Array.map to extract the value. Then spread to Math.max for the final result.

Upvotes: 0

Cid
Cid

Reputation: 15247

You can use a good old loop

let d = {
"A": [ {"value": 10}, {"value": 20}, {"value": 30} ],
"B": [ {"value": 50}, {"value": 60}, {"value": 1000} ],
}

let maxValue;
for (let key in d)
{
  for (let i = 0, len = d[key].length; i < len; ++i)
  {
    if (maxValue === undefined || maxValue < d[key][i].value)
      maxValue = d[key][i].value;
  }
}

console.log(maxValue);

Upvotes: 0

Ziv Ben-Or
Ziv Ben-Or

Reputation: 1194

d = {
    "A": [{ "value": 10 }, { "value": 20 }, { "value": 30 }],
    "B": [{ "value": 50 }, { "value": 60 }, { "value": 1000 }],
}


var maxValue = Math.max.apply(null,Object.keys(d).map(key => Math.max.apply(null,d[key].map(x => x.value))));

console.log(maxValue);

Upvotes: 0

Kunal Mukherjee
Kunal Mukherjee

Reputation: 5853

Try something like this by flattening the values first then sorting it in ascending order and taking the last element out of the sorted array:

const data = {
		"A": [ {"value": 10}, {"value": 20}, {"value": 30 } ],
		"B": [ {"value": 50}, {"value": 60}, {"value": 1000} ],
};


const highestValue = Object.values(data)
.flatMap(x => x)
.sort((a, b) => a.value - b.value)
.slice(-1);

console.log(highestValue);

Upvotes: 0

Pinetree
Pinetree

Reputation: 637

If you want es5 code, try this:

var d = {
"A": [ {"value": 10}, {"value": 20}, {"value": 30} ],
"B": [ {"value": 50}, {"value": 60}, {"value": 1000} ],
};

var results = [];
for(var key in d)
{
    d[key].forEach(function (obj){
        results.push(obj.value);
    });
}
console.log(Math.max.apply(null, results));

Upvotes: 0

Jack Bashford
Jack Bashford

Reputation: 44087

Use Object.values, flatMap and Math.max with spreading.

const d = {"A":[{"value":10},{"value":20},{"value":30}],"B":[{"value":50},{"value":60},{"value":1000}]};
const res = Math.max(...Object.values(d).flat().flatMap(Object.values));
console.log(res);

Because flat isn't well supported (and neither is flatMap) you can use reduce as well.

const d = {"A":[{"value":10},{"value":20},{"value":30}],"B":[{"value":50},{"value":60},{"value":1000}]};
const res = Math.max(...Object.values(d).map(e => e.map(Object.values)).reduce((a, c) => [].concat(...a, ...c)));
console.log(res);

Upvotes: 2

Nenad Vracar
Nenad Vracar

Reputation: 122027

You can use spread syntax ... in Math.max after you map and flatten the array.

const d = {
  "A": [ {"value": 10}, {"value": 20}, {"value": 30} ],
  "B": [ {"value": 50}, {"value": 60}, {"value": 1000} ],
}

const max = Math.max(...[].concat(...Object.values(d)).map(({value}) => value))
console.log(max)

Upvotes: 7

Related Questions