a

20:46:20 29/3/2025 - 1 views -
JS

Tính điểm trung bình

Để tạo một hàm tính điểm trung bình mà có thể truyền vào bao nhiêu tham số tùy ý, bạn có thể sử dụng các kỹ thuật sau trong JavaScript:


Sử dụng arguments object

Trong JavaScript, mọi hàm đều có một đối tượng đặc biệt gọi là arguments. Đây là một mảng-like object chứa tất cả các tham số được truyền vào hàm, ngay cả khi chúng không được khai báo rõ ràng.

Ví dụ:

function calculateAverage() {
    let sum = 0;
    for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
    return arguments.length > 0 ? sum / arguments.length : 0;
}

// Sử dụng
console.log(calculateAverage(10, 20, 30)); // Output: 20
console.log(calculateAverage(5, 15, 25, 35, 45)); // Output: 25
console.log(calculateAverage()); // Output: 0

Nhược điểm của arguments:

  • Không phải là một mảng thực sự, nên không thể sử dụng các phương thức của mảng như .map, .filter, v.v.
  • Khó đọc và khó bảo trì.

Sử dụng Rest Parameters (...args)

Rest parameters là cách hiện đại và dễ đọc hơn để xử lý các tham số không cố định. Bạn có thể sử dụng cú pháp ...args để thu thập tất cả các tham số truyền vào thành một mảng thực sự.

Ví dụ:

function calculateAverage(...args) {
    if (args.length === 0) return 0; // Tránh chia cho 0 nếu không có tham số
    const sum = args.reduce((total, num) => total + num, 0);
    return sum / args.length;
}

// Sử dụng
console.log(calculateAverage(10, 20, 30)); // Output: 20
console.log(calculateAverage(5, 15, 25, 35, 45)); // Output: 25
console.log(calculateAverage()); // Output: 0

Ưu điểm của Rest Parameters:

  • Đơn giản và dễ hiểu.
  • args là một mảng thực sự, nên bạn có thể sử dụng các phương thức của mảng như .reduce, .map, .filter, v.v.

Xử lý đầu vào không hợp lệ

Để đảm bảo hàm hoạt động ổn định, bạn nên kiểm tra xem các tham số truyền vào có phải là số hay không. Nếu không phải số, bạn có thể bỏ qua hoặc xử lý lỗi.

Ví dụ:

function calculateAverage(...args) {
    const validNumbers = args.filter(num => typeof num === "number" && !isNaN(num));
    if (validNumbers.length === 0) return 0; // Trả về 0 nếu không có số hợp lệ
    const sum = validNumbers.reduce((total, num) => total + num, 0);
    return sum / validNumbers.length;
}

// Sử dụng
console.log(calculateAverage(10, 20, "30", null, undefined)); // Output: 15
console.log(calculateAverage("abc", NaN, {}, [])); // Output: 0
console.log(calculateAverage(5, 15, 25, 35, 45)); // Output: 25

Giải thích:

  • filter được sử dụng để loại bỏ các giá trị không phải số.
  • isNaN đảm bảo rằng các giá trị như NaN cũng bị loại bỏ.

Hỗ trợ truyền mảng làm tham số

Nếu bạn muốn hỗ trợ việc truyền một mảng làm tham số, bạn có thể kết hợp spread operator (...) với rest parameters.

Ví dụ:

function calculateAverage(...args) {
    const numbers = args.flat(); // Chuyển đổi mảng lồng nhau thành mảng phẳng
    const validNumbers = numbers.filter(num => typeof num === "number" && !isNaN(num));
    if (validNumbers.length === 0) return 0;
    const sum = validNumbers.reduce((total, num) => total + num, 0);
    return sum / validNumbers.length;
}

// Sử dụng
console.log(calculateAverage(10, 20, [30, 40], 50)); // Output: 30
console.log(calculateAverage([5, 10, 15])); // Output: 10
console.log(calculateAverage([])); // Output: 0

Giải thích:

  • args.flat() giúp chuyển đổi mảng lồng nhau thành mảng phẳng.
  • Điều này cho phép bạn truyền cả số và mảng vào hàm.

Tạo hàm tính trung bình với currying

Bạn cũng có thể tạo một hàm tính trung bình bằng cách sử dụng kỹ thuật currying, cho phép bạn truyền tham số từng phần.

Ví dụ:

function calculateAverage(...args) {
    return function (...moreArgs) {
        const allArgs = args.concat(moreArgs);
        const validNumbers = allArgs.filter(num => typeof num === "number" && !isNaN(num));
        if (validNumbers.length === 0) return 0;
        const sum = validNumbers.reduce((total, num) => total + num, 0);
        return sum / validNumbers.length;
    };
}

// Sử dụng
const avg = calculateAverage(10, 20)(30, 40); // Kết hợp hai lần gọi
console.log(avg); // Output: 25

Giải thích:

  • Hàm calculateAverage trả về một closure, cho phép bạn tiếp tục thêm tham số ở các lần gọi tiếp theo.

Tổng kết

Dưới đây là các cách phổ biến để tạo một hàm tính điểm trung bình có thể truyền bao nhiêu tham số tùy ý:

  1. Sử dụng arguments object: Phù hợp với các phiên bản cũ của JavaScript.
  2. Sử dụng Rest Parameters (...args): Cách hiện đại và dễ đọc hơn.
  3. Xử lý đầu vào không hợp lệ: Kiểm tra và lọc các tham số không phải số.
  4. Hỗ trợ truyền mảng: Cho phép truyền cả số và mảng làm tham số.
  5. Currying: Tạo hàm tính trung bình với khả năng truyền tham số từng phần.

Phương pháp được khuyến nghị là sử dụng Rest Parameters vì nó dễ đọc, dễ bảo trì và tương thích tốt với các tính năng hiện đại của JavaScript.


Code hoàn chỉnh (ưu tiên sử dụng Rest Parameters):

function calculateAverage(...args) {
    const validNumbers = args.filter(num => typeof num === "number" && !isNaN(num));
    if (validNumbers.length === 0) return 0;
    const sum = validNumbers.reduce((total, num) => total + num, 0);
    return sum / validNumbers.length;
}

// Sử dụng
console.log(calculateAverage(10, 20, 30)); // Output: 20
console.log(calculateAverage(5, 15, 25, 35, 45)); // Output: 25
console.log(calculateAverage()); // Output: 0
console.log(calculateAverage("abc", NaN, {}, [])); // Output: 0

Hy vọng hướng dẫn trên giúp bạn hiểu rõ cách tạo một hàm tính điểm trung bình linh hoạt trong JavaScript!