9

How can i find median values from array in javascript

this is my array

var data = [       
    { values: 4 }, 
    { values: 4 }, 
    { values: 4 }, 
    { values: 5 }, 
    { values: 2 }, 
    { values: 6 }, 
    { values: 6 },
    { values: 5 }
];

and i have tried this code

 function findMedian(m) {
        var middle = m.length - 1 / 2;
        if (m.length - 1 % 2 == 1) {
            return m[middle];
        } else {
            return (m[middle - 1] + m[middle]) / 2.0;
        }

    }

But it's return NaN value

My calculation formula is

Find the median of the data. Place the number of data in ascending order. Then, mark the place whose value we take into account when calculating the median.

JBallin
  • 8,481
  • 4
  • 46
  • 51
  • The middle it's a decimal number, and so array[7.5] it's undefined (the index should be integer, you can use *Math.floor* or *Math.ceil*). Also, I don't know if that alogrithm it's correct. – sergioFC Aug 14 '14 at 10:24
  • You are doing *var middle = m.length - (1 / 2);* (look at the parenthesis). Division operator has precedence over minus operator. – sergioFC Aug 14 '14 at 10:26

7 Answers7

12

This will do what you need - at the moment you've no logic to cope with reading the .values field out of each element of the array:

function findMedian(data) {

    // extract the .values field and sort the resulting array
    var m = data.map(function(v) {
        return v.values;
    }).sort(function(a, b) {
        return a - b;
    });

    var middle = Math.floor((m.length - 1) / 2); // NB: operator precedence
    if (m.length % 2) {
        return m[middle];
    } else {
        return (m[middle] + m[middle + 1]) / 2.0;
    }
}

EDIT I've padded out the code a bit compared to my original answer for readability, and included the (surprising to me) convention that the median of an even-length set be the average of the two elements either side of the middle.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
8

For an array of numbers, e.g. [1,6,3,9,28,...]

// calculate the median
function median(arr){
  arr.sort(function(a, b){ return a - b; });
  var i = arr.length / 2;
  return i % 1 == 0 ? (arr[i - 1] + arr[i]) / 2 : arr[Math.floor(i)];
}

What the code is doing:

  1. Sort the numbers so that they are in order by value.
  2. Find out the median's index in the array. If the array's length is even, the median is the average of the two numbers on either side of the index.
  3. For arrays of odd length, it's easy to pluck out the middle number. But for arrays of even length, it's not. So, you test to find out whether your array is odd- or even-lengthed by finding out if dividing the array's length by two returns a whole number or not. If it's a whole number, that means the array's length is even, and you have to calculate the average of the two numbers on either side of the median.

In your question, your array can be flattened like so:

var myArray = data.map(function(d){ return d.values; });

And to get the median, use the function above like so:

var myMedian = median(myArray); // 4.5
Harry Stevens
  • 1,373
  • 1
  • 15
  • 18
6

Here about two things you have to be careful.

1) Operator precedence

When you are saying

var middle = m.length - 1 / 2;

It is same as

 var middle = m.length - 0.5; //Because / has much precedence than -

So you should say

 var middle = (m.length - 1) / 2;

Same problem with m.length - 1 % 2

2) You are not rounding middle so it's looking for decimal indexes in array. Which I think will return undefined.

Mritunjay
  • 25,338
  • 7
  • 55
  • 68
2

In case you were wondering how to find median without using conditionals, here you are :)

Mind ES6.

/**
 * Calculate median of array of numbers
 * @param {Array<Number>} arr
 * @return {Number}
 */
function median(arr) {
    arr = [...arr].sort((a, b) => a - b);
    return (arr[arr.length - 1 >> 1] + arr[arr.length >> 1]) / 2;
}

To answer the question:

median(data.map(x => x.values));
disfated
  • 10,633
  • 12
  • 39
  • 50
0

Here's a snippet that allows you to generate an array of numbers with either even or odd length. The snippet then sorts the array and calculates the median, finally printing the sorted array and the median.

(function() {
  function makeNumArray(isEven) {
    var randomNumArr = [];
    var limit = isEven ? 8 : 9;
    for (var i = 0; i < limit; i++) {
      randomNumArr.push(Math.ceil(Math.random() * 10));
    }
    return randomNumArr;
  }

  function getMedian(arrOfNums) {
    var result = [];
    var sortedArr = arrOfNums.sort(function(num1, num2) {
      return num1 - num2;
    });
    result.push("sortedArr is: [" + sortedArr.toString() + "]");
    var medianIndex = Math.floor(sortedArr.length / 2);
    if (arrOfNums.length % 2 === 0) {
      result.push((sortedArr[medianIndex-1] + sortedArr[medianIndex]) / 2);
      return result;
    } else {
      result.push(sortedArr[medianIndex]);
      return result;
    }
  }

  function printMedian(resultArr) {
    var presentDiv = document.querySelector('#presentResult');
    var stringInsert = '<div id="sortedArrDiv">' + resultArr[0].toString() + '<br>' + 'the median is: ' + resultArr[1].toString() + '</div>';
    if (!document.querySelector('#sortedArrDiv')) {
      presentDiv.insertAdjacentHTML('afterbegin', stringInsert);
    } else {
      document.querySelector('#sortedArrDiv').innerHTML = resultArr[0].toString() + "<br>" + 'the median is: ' + resultArr[1].toString();
    }
  };

  function printEven() {
    printMedian(getMedian(makeNumArray(1)));
  }

  function printOdd() {
    printMedian(getMedian(makeNumArray(0)));
  }


  (document.querySelector("#doEven")).addEventListener('click', printEven, false);

  (document.querySelector("#doOdd")).addEventListener('click', printOdd, false);


})();
#presentResult {
  width: 70%;
  margin: 2% 0;
  padding: 2%;
  border: solid black;
}
<h4>Calculate the median of an array of numbers with even (static length of 8) or odd (static length of 9) length. </h4>
<input type="button" value="Even length array of random nums" id="doEven">
<input type="button" value="Odd length array of random nums" id="doOdd">
<div id="presentResult"></div>
cssimsek
  • 1,255
  • 14
  • 20
0
function median(a){
let arrlength = a.length;
if((arrlength%2) == 0){
let c = arrlength/2;
let b = (a[c]+a[c-1])/2;
return b;
}
else{
let e=Math.floor(arrlength/2);
return a[e];
}
}
median([1, 2, 10, 100]);

Try this simple one.

Madhan
  • 107
  • 12
-1
Findmedian(arr) {

arr = arr.sort(function(a, b){ return a - b; });

 var i = arr.length / 2;


var result =  i % 1 == 0 ? parseInt((arr[i - 1] + arr[i]) / 2) + ',' + 
parseInt(arr[i]) : arr[Math.floor(i)];

return result;

}

it returns for odd number of array elements.

Zoe
  • 27,060
  • 21
  • 118
  • 148
Brijesh
  • 352
  • 5
  • 17