Odd number of elements in an array

Viewed 775

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)
}

1 Answers

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)
}

Related