0

I'm trying to get the maximum value of an element from an array of objects:

var graph = {};

graph.data = [
{x: 2008, y: 7.2},
{x: 2009, y: 8.1},
{x: 2010, y: 7.7},
{x: 2011, y: 6.8},
{x: 2012, y: 6.7}
];

to get the maximum, I use the following:

var highest = graph.data[0].y;
for (var i = graph.data.length - 1; i >=1; i--) {
    highest = Math.max(highest, graph.data[i].y);
}

which gives me the correct result. However when I try to make a higher order function, so I can reuse it:

var getMax = function (arr, para) {
    var highest = arr[0].para;
    for (var i = arr.length; i >= 1; i--) {
        highest = Math.max(highest, arr[i].para);
    }
}

and I try to use it like this:

getMax(graph.data, y);

I get an error, saying Uncaught: "Reference Error: y is not defined", any ideas? I did try to use the bracket notation instead of the dot one for para, it didn't work

1
  • 3
    This is not a higher-order function... Commented Dec 22, 2014 at 0:12

3 Answers 3

1

Try this:

var getMax = function (arr, para) {
    var highest = arr[0][para];

    for (var i = arr.length - 1; i >= 1; i--) {
        highest = Math.max(highest, arr[i][para]);
    }
    return highest;
}

getMax(graph.data, 'y');

You can't just pass y because y is not defined, so pass 'y' as a character. Also you need to return highest from you function and you need start your loop from length - 1

Sign up to request clarification or add additional context in comments.

1 Comment

Well spotted on the -1, thanks for the complete answer
0

A higher-order function is a function that takes functions as arguments, and/or returns a function. You can do this with higher-order functions, like pluck:

var pluck = function(x) {
  return function(xs) {
    return xs[x]
  }
}

var max = function(x, y) {
  return Math.max(x, y)
}

So you get:

var getMax = function(xs, x) {
  return xs.map(pluck(x)).reduce(max)
}

var result = getMax(graph.data, 'y')

console.log(result) //=> 8.1

1 Comment

My bad, I didn't use the correct terminology, but I appreciate your answer that gives me food for thought on how to organize my code.
0

You can use reduce for this also:

graph.data.reduce(function(pre, cur){return pre.y > cur.y? pre : cur}).y;

Which can be turned into a function as:

function getBiggest(arr, p) {
  return arr.reduce(function (pre, cur){return pre[p] > cur[p]? pre:cur})[p];
}

getBiggest(graph.data, 'y') // 8.1

Writing it as a loop might be a bit more code, but generally runs faster and may be easier to maintain:

function getBiggest(arr, p) {
  for (var i=0, x=-Infinity, iLen=arr.length; i<iLen; i++) {
    if (x < arr[i][p]) x = arr[i][p];
  }
  return x;
}

I think the use of Math.max to get the larger of two values is overkill, but it's good for getting the maximum of many values, e.g.:

function getBiggest(arr, p) {
  return Math.max.apply(Math, arr.map(function(v){return v[p]}));
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.