3

When trying to figure out how to get the median value of an array, I first wanted to figure out if the number of elements in the array is odd or even.

  • If the number is odd then the console will log the element in the middle.
  • If there's an even number of elements I want the console to log 'Not an odd number of numbers'.

I'm sure there's an easier way to get the median of an array, but I want to figure that out by myself. Right now I just need help with why the console logs the number 1 in my second test of an array, even though there is an even number of elements in that array? It worked fine in the first and third test but not the second one...why?

function median (arr) {
  let sorted = arr.sort((a, b) => a-b)
  let midIndex = sorted.splice(0, sorted.length / 2)
  if (arr.length %2 != 0) {
    return midIndex[midIndex.length-1]
  } else {
    return "Not an odd number of numbers"
  }
  
}

try {
  let result = median([4, 8, 2, 4, 5])
  console.log(result)                   // -> 4

  result = median([-5, 1, 5, 2, 4, 1])  // -> 1
  console.log(result)

  result = median([5, 1, 1, 1, 3, -2, 2, 5, 7, 4, 5, 6])  // -> Not an odd number of numbers
  console.log(result)
} catch (e) {
  console.error(e.message)
}
Andreas
  • 21,535
  • 7
  • 47
  • 56
  • [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) -> First introduce the problem, then post the relevant code/[mcve] – Andreas Sep 22 '20 at 10:19
  • My answer still stands for why you're not getting the result you expect, but I struggle to see what the purpose of the `splice` call is at all for getting the median. – Jamiec Sep 22 '20 at 10:26

1 Answers1

2

Because splice actually changes the length of the original array - it does not create a new array. You can see this by taking a note of the length before calling splice

function median (arr) {
  var initLength = arr.length;
  let sorted = arr.sort((a, b) => a-b)
  let midIndex = sorted.splice(0, sorted.length / 2)
  console.log(initLength, arr.length);
  if (arr.length %2 != 0) {
    return midIndex[midIndex.length-1]
  } else {
    return "Not an odd number of numbers"
  }
  
}

try {
  let result = median([4, 8, 2, 4, 5])
  //console.log(result)                   // -> 4

  result = median([-5, 1, 5, 2, 4, 1])  // -> 1
  //console.log(result)

  result = median([5, 1, 1, 1, 3, -2, 2, 5, 7, 4, 5, 6])  // -> Not an odd number of numbers
  //console.log(result)
} catch (e) {
  console.error(e.message)
}

So splicing an array of 6 in half gives a length of 3 which is odd. Instead use the original array length and it does what you expected:

function median (arr) {
  var initLength = arr.length;
  let sorted = arr.sort((a, b) => a-b)
  let midIndex = sorted.splice(0, sorted.length / 2)
  if (initLength %2 != 0) {
    return midIndex[midIndex.length-1]
  } else {
    return "Not an odd number of numbers"
  }
  
}

try {
  let result = median([4, 8, 2, 4, 5])
  console.log(result)                   // -> 4

  result = median([-5, 1, 5, 2, 4, 1])  // -> 1
  console.log(result)

  result = median([5, 1, 1, 1, 3, -2, 2, 5, 7, 4, 5, 6])  // -> Not an odd number of numbers
  console.log(result)
} catch (e) {
  console.error(e.message)
}
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • OMG thank you! You're a lifesaver. Thank you for explaining it to me in a way that's easy for me to understand. I really appreciate it! –  Sep 22 '20 at 18:46