DocsHub
JavascriptIntermediate

Array Statistics

Build a tool that calculates statistics — sum, average, min, max, median — from a list of numbers entered by the user.

Array Statistics

Problem

Build a tool where the user enters a list of numbers separated by commas, and the app calculates and displays statistics — sum, average, minimum, maximum, range, and median.

Input: 4, 8, 15, 16, 23, 42

Output:
Count:   6
Sum:     108
Average: 18
Min:     4
Max:     42
Range:   38
Median:  15.5

Input: 7
Output:
Count: 1   Sum: 7   Average: 7   Min: 7   Max: 7   Range: 0   Median: 7

Input: (empty)
Output: Please enter at least one number

Logic

  1. Select the input, button, and result display
  2. Read and parse the comma-separated numbers
  3. Validate that all entries are valid numbers
  4. Calculate sum using reduce
  5. Calculate average from sum and count
  6. Find min and max using Math.min and Math.max
  7. Calculate range as max - min
  8. Calculate median — sort the array, find the middle value(s)
  9. Display all stats in a grid

Flow

no yes User clicks Calculate Read and split input All valid numbers? Show error Convert to numbers Calculate sum, average, min, max, range Sort copy of array Find median from sorted array Display all stats

HTML Structure

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Array Statistics</title>
    <style>
      body {
        font-family: sans-serif;
        max-width: 480px;
        margin: 60px auto;
        padding: 0 20px;
      }

      .input-row {
        display: flex;
        gap: 10px;
        margin-bottom: 16px;
      }

      .input-row input {
        flex: 1;
        padding: 12px;
        font-size: 1rem;
        border: 2px solid #ccc;
        border-radius: 8px;
        outline: none;
        box-sizing: border-box;
      }

      .input-row input:focus {
        border-color: #555;
      }

      .input-row button {
        padding: 12px 20px;
        font-size: 1rem;
        font-weight: 600;
        background: #111;
        color: #fff;
        border: none;
        border-radius: 8px;
        cursor: pointer;
      }

      .input-row button:hover {
        opacity: 0.85;
      }

      #error {
        color: #c0392b;
        font-size: 0.9rem;
        margin-bottom: 12px;
        display: none;
      }

      /* stats grid — 2 columns */
      #stats {
        display: none;
        grid-template-columns: repeat(2, 1fr);
        gap: 10px;
      }

      .stat-card {
        background: #f5f5f5;
        border-radius: 8px;
        padding: 14px 16px;
      }

      .stat-card .label {
        font-size: 0.8rem;
        color: #888;
        margin-bottom: 4px;
      }

      .stat-card .value {
        font-size: 1.4rem;
        font-weight: 700;
        color: #111;
      }
    </style>
  </head>
  <body>
    <h1>Array Statistics</h1>

    <div class="input-row">
      <input
        type="text"
        id="numbers-input"
        placeholder="e.g. 4, 8, 15, 16, 23, 42"
      />
      <button id="calculate-btn">Calculate</button>
    </div>

    <div id="error"></div>

    <!-- stat cards rendered here -->
    <div id="stats">
      <div class="stat-card">
        <div class="label">Count</div>
        <div class="value" id="stat-count">-</div>
      </div>
      <div class="stat-card">
        <div class="label">Sum</div>
        <div class="value" id="stat-sum">-</div>
      </div>
      <div class="stat-card">
        <div class="label">Average</div>
        <div class="value" id="stat-average">-</div>
      </div>
      <div class="stat-card">
        <div class="label">Median</div>
        <div class="value" id="stat-median">-</div>
      </div>
      <div class="stat-card">
        <div class="label">Min</div>
        <div class="value" id="stat-min">-</div>
      </div>
      <div class="stat-card">
        <div class="label">Max</div>
        <div class="value" id="stat-max">-</div>
      </div>
      <div class="stat-card">
        <div class="label">Range</div>
        <div class="value" id="stat-range">-</div>
      </div>
    </div>

    <script src="script.js"></script>
  </body>
</html>

Solution

// Step 1 — select elements
const numbersInput = document.querySelector("#numbers-input");
const calculateBtn = document.querySelector("#calculate-btn");
const error = document.querySelector("#error");
const stats = document.querySelector("#stats");

// Step 2 — listen for click and Enter key
calculateBtn.addEventListener("click", calculateStats);

numbersInput.addEventListener("keydown", (e) => {
  if (e.key === "Enter") calculateStats();
});

function calculateStats() {
  const value = numbersInput.value.trim();

  // Step 3 — handle empty input
  if (!value) {
    showError("Please enter at least one number.");
    return;
  }

  // Step 4 — split, trim, and filter out empty entries
  const parts = value
    .split(",")
    .map((item) => item.trim())
    .filter((item) => item !== "");

  // Step 5 — validate all entries are numbers
  const hasInvalid = parts.some((item) => isNaN(Number(item)));

  if (hasInvalid) {
    showError("Please enter valid numbers only.");
    return;
  }

  // Step 6 — convert to numbers
  const numbers = parts.map(Number);

  // Step 7 — calculate sum using reduce
  // reduce starts with 0 and adds each number to the running total
  const sum = numbers.reduce((total, n) => total + n, 0);

  // Step 8 — calculate average
  const average = sum / numbers.length;

  // Step 9 — find min and max
  // spread the array as individual arguments to Math.min/max
  const min = Math.min(...numbers);
  const max = Math.max(...numbers);

  // Step 10 — calculate range
  const range = max - min;

  // Step 11 — calculate median
  const median = calculateMedian(numbers);

  // Step 12 — display all stats
  showStats({
    count: numbers.length,
    sum,
    average,
    min,
    max,
    range,
    median
  });
}

// Step 13 — median calculation function
function calculateMedian(numbers) {
  // create a sorted copy — do not mutate the original array
  // [...numbers] spreads into a new array before sorting
  const sorted = [...numbers].sort((a, b) => a - b);

  const middle = Math.floor(sorted.length / 2);

  // if length is odd — return the exact middle value
  // if length is even — return the average of the two middle values
  if (sorted.length % 2 !== 0) {
    return sorted[middle];
  }

  return (sorted[middle - 1] + sorted[middle]) / 2;
}

// helper — formats a number to at most 2 decimal places
// removes trailing zeros — 18.00 becomes 18, 18.50 stays 18.5
function formatNumber(num) {
  return Math.round(num * 100) / 100;
}

// helper — displays the calculated stats
function showStats(data) {
  error.style.display = "none";
  stats.style.display = "grid";

  document.querySelector("#stat-count").textContent = data.count;
  document.querySelector("#stat-sum").textContent = formatNumber(data.sum);
  document.querySelector("#stat-average").textContent = formatNumber(data.average);
  document.querySelector("#stat-median").textContent = formatNumber(data.median);
  document.querySelector("#stat-min").textContent = data.min;
  document.querySelector("#stat-max").textContent = data.max;
  document.querySelector("#stat-range").textContent = data.range;
}

function showError(message) {
  error.textContent = message;
  error.style.display = "block";
  stats.style.display = "none";
}

Code Execution

Trace through input "4, 8, 15, 16, 23, 42":

StepCodeResult
Split and clean["4","8","15","16","23","42"]
Convert.map(Number)[4, 8, 15, 16, 23, 42]
Sumreduce((t,n) => t+n, 0)108
Average108 / 618
MinMath.min(...numbers)4
MaxMath.max(...numbers)42
Range42 - 438

Median trace for [4, 8, 15, 16, 23, 42] (6 items — even):

StepCodeResult
Sorted[4, 8, 15, 16, 23, 42] (already sorted)same
middleMath.floor(6 / 2)3
Even check6 % 2 !== 0false
Median(sorted[2] + sorted[3]) / 2(15 + 16) / 215.5

Median trace for [7] (1 item — odd):

StepCodeResult
Sorted[7]same
middleMath.floor(1 / 2)0
Odd check1 % 2 !== 0true
Mediansorted[0]7

Output

Input: 4, 8, 15, 16, 23, 42
→ Count: 6  Sum: 108  Average: 18  Median: 15.5  Min: 4  Max: 42  Range: 38

Input: 7
→ Count: 1  Sum: 7  Average: 7  Median: 7  Min: 7  Max: 7  Range: 0

Input: (empty)
→ Please enter at least one number

On this page