1

I have the following object:

var questions = [{
    'question_id': 245,
    'question': 'Question 1',
    'ordinal': 1,
    'master_difficulty': 1,
    'overridden_difficulty': ''
},{
    'question_id': 34,
    'question': 'Question 2',
    'ordinal': 2,
    'master_difficulty': 1,
    'overridden_difficulty': ''
},{
    'question_id': 656,
    'question': 'Question 3',
    'ordinal': 3,
    'master_difficulty': 1,
    'overridden_difficulty': ''
},{
    'question_id': 86,
    'question': 'Question 4',
    'ordinal': 4,
    'master_difficulty': 1,
    'overridden_difficulty': ''
}]

And I want to get the highest ordinal value from it.

e.g. var highestOrdinal = highestOrdinalFunction(questions);

Where highestOrdinalFunction will return the highest ordinal number.

So in this case it would return 4.

Could Math.max work for this?

5
  • 2
    stackoverflow.com/questions/22949597/… Commented Mar 11, 2016 at 11:17
  • 4
    Math.max.apply(Math, questions.map(q => q.ordinal)); Commented Mar 11, 2016 at 11:18
  • @Yoshi: Should have posted that as an answer. Commented Mar 11, 2016 at 11:27
  • @T.J.Crowder I thought there has to be ton's of duplicates for this question, so I expected it to get closed very quick. Commented Mar 11, 2016 at 11:29
  • @Yoshi: That's a fair point, and Ahbap had already found it for us as well. Commented Mar 11, 2016 at 11:36

4 Answers 4

4

Array#reduce (spec | MDN) is the idiomatic way to do things like this:

function highestOrdinalFunction() {
    return questions.reduce(function(previous, entry) {
        return previous === undefined || entry.ordinal > previous ? entry.ordinal : previous;
    }, undefined);
}

Array#reduce calls a callback repeatedly, passing in the callback's previous return value, which is seeded with the second argument to reduce. That thing is usually called the "accumulator" for the reduce operation. The result of reduce is the final value of the accumulator.

The above will return undefined if questions is empty.

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

3 Comments

What if ordinal values present in between -2 to -infinity ?
@RajaprabhuAravindasamy: Good point!!
@RajaprabhuAravindasamy: Fixed.
2

I guess this is what you are looking for:

Math.max.apply(Math,questions.map(function(ques){return ques.ordinal;}))

please refer to Array.prototype.map for more info on how map() works.

Comments

0

We can just sort the objects within that array by the ordinal value and then return the first entry.

function highestOrdinalFunction( questions ) {
    return questions.sort( ( a, b ) => a.ordinal - b.ordinal )[ 0 ].ordinal;
}

It's probably a better idea to combine Array.prototype.map alongside Math.max() in this instance:

Math.max.apply( null, questions.map(q => q.ordinal) );

2 Comments

Sorting is an awful lot of work to do just to find the highest one.
You're right TJ, math.max seems to fit better.
0

You can find the max value two ways. You can either pass a function to map the property's value or call the property directly on the item. The result of these would be the mapped value to be applied the the Math.max calculation, in respect to the list of items.

Math.prototype.max

var questions = [
  {'question_id':245,'question':'Question 1','ordinal':1,'master_difficulty':1,'overridden_difficulty':''},
  {'question_id':34,'question':'Question 2','ordinal':2,'master_difficulty':1,'overridden_difficulty':''},
  {'question_id':656,'question':'Question 3','ordinal':3,'master_difficulty':1,'overridden_difficulty':''},
  {'question_id':86,'question':'Question 4','ordinal':4,'master_difficulty':1,'overridden_difficulty':''}
]

document.body.innerHTML =  'Via Function: ' + highestOrdinalValueFn(questions) + '\n';
document.body.innerHTML += 'Via Property: ' + highestOrdinalValueProp(questions);

// #1 : Via function
function highestOrdinalValueFn(items) {
  return max(items, function() {
    return this.ordinal;
  });
}
// #2 : Via property
function highestOrdinalValueProp(items) {
  return max(items, 'ordinal');
}

function max(list, prop) {
  return Math.max.apply(Math, list.map(function(item) {
    return isFunction(prop) ? prop.call(item) : item[prop];
  }));
}

function isFunction(fn) {
  return fn && {}.toString.call(fn) === '[object Function]';
}
body { white-space: pre; font-family: monospace; }


Array.prototype.reduce

var questions = [
  {'question_id':245,'question':'Question 1','ordinal':1,'master_difficulty':1,'overridden_difficulty':''},
  {'question_id':34,'question':'Question 2','ordinal':2,'master_difficulty':1,'overridden_difficulty':''},
  {'question_id':656,'question':'Question 3','ordinal':3,'master_difficulty':1,'overridden_difficulty':''},
  {'question_id':86,'question':'Question 4','ordinal':4,'master_difficulty':1,'overridden_difficulty':''}
]

document.body.innerHTML = highestValue(questions, 'ordinal');

function highestValue(items, prop) {
  return compare(items, function(curr, prev) {
    return maxNumericComparator(curr, prev, prop);
  })[prop];
}

function maxNumericComparator(curr, prev, prop) {
  if (curr && !prev) return -1;
  if (!curr && prev) return 1;
  if (curr[prop] && !prev[prop]) return -1;
  if (!curr[prop] && prev[prop]) return 1;
  if (curr[prop] > prev[prop]) return -1;
  if (curr[prop] < prev[prop]) return 1;
  return 0;
};

function compare(list, comparator) {
  return list.reduce(function(max, item) {
    return comparator(item, max) < 0 ? item : max;
  }, null);
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.