JavaScript 流程控制与数组实战练习案例
一、基础练习
1. 数组遍历与条件判断
// 练习1:找出数组中的偶数并计算它们的和
function sumEvenNumbers(arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] % 2 === 0) {
sum += arr[i];
}
}
return sum;
}
// 测试
console.log(sumEvenNumbers([1, 2, 3, 4, 5, 6])); // 12
console.log(sumEvenNumbers([10, 15, 20, 25])); // 30
// 练习2:使用forEach实现相同功能
function sumEvenNumbersForEach(arr) {
let sum = 0;
arr.forEach(num => {
if (num % 2 === 0) {
sum += num;
}
});
return sum;
}
2. 数组筛选与转换
// 练习3:筛选出成绩及格的学生
function filterPassingStudents(scores) {
const passingStudents = [];
for (let i = 0; i < scores.length; i++) {
if (scores[i] >= 60) {
passingStudents.push(scores[i]);
}
}
return passingStudents;
}
// 练习4:将学生成绩转换为等级
function convertToGrades(scores) {
const grades = [];
for (let i = 0; i < scores.length; i++) {
if (scores[i] >= 90) {
grades.push('A');
} else if (scores[i] >= 80) {
grades.push('B');
} else if (scores[i] >= 70) {
grades.push('C');
} else if (scores[i] >= 60) {
grades.push('D');
} else {
grades.push('F');
}
}
return grades;
}
二、中级练习
1. 数组操作综合
// 练习5:统计数组中各元素出现的次数
function countOccurrences(arr) {
const countMap = {};
for (let i = 0; i < arr.length; i++) {
const element = arr[i];
if (countMap[element]) {
countMap[element]++;
} else {
countMap[element] = 1;
}
}
return countMap;
}
// 测试
console.log(countOccurrences(['apple', 'banana', 'apple', 'orange', 'banana', 'apple']));
// { apple: 3, banana: 2, orange: 1 }
// 练习6:找出数组中的最大值和最小值
function findMinMax(arr) {
if (arr.length === 0) return { min: null, max: null };
let min = arr[0];
let max = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
if (arr[i] > max) {
max = arr[i];
}
}
return { min, max };
}
2. 数组排序与搜索
// 练习7:实现冒泡排序
function bubbleSort(arr) {
const sortedArr = [...arr]; // 创建副本,不修改原数组
for (let i = 0; i < sortedArr.length - 1; i++) {
for (let j = 0; j < sortedArr.length - 1 - i; j++) {
if (sortedArr[j] > sortedArr[j + 1]) {
// 交换元素
const temp = sortedArr[j];
sortedArr[j] = sortedArr[j + 1];
sortedArr[j + 1] = temp;
}
}
}
return sortedArr;
}
// 练习8:二分查找(数组必须已排序)
function binarySearch(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) {
return mid; // 找到目标,返回索引
} else if (arr[mid] < target) {
left = mid + 1; // 目标在右侧
} else {
right = mid - 1; // 目标在左侧
}
}
return -1; // 未找到
}
三、高级实战案例
1. 学生成绩管理系统
// 练习9:学生成绩统计分析
class StudentGradeSystem {
constructor() {
this.students = [];
}
// 添加学生成绩
addStudent(name, score) {
this.students.push({ name, score });
}
// 计算平均分
calculateAverage() {
if (this.students.length === 0) return 0;
let sum = 0;
for (let i = 0; i < this.students.length; i++) {
sum += this.students[i].score;
}
return sum / this.students.length;
}
// 找出最高分和最低分
findScoreRange() {
if (this.students.length === 0) return { highest: null, lowest: null };
let highest = this.students[0];
let lowest = this.students[0];
for (let i = 1; i < this.students.length; i++) {
if (this.students[i].score > highest.score) {
highest = this.students[i];
}
if (this.students[i].score < lowest.score) {
lowest = this.students[i];
}
}
return { highest, lowest };
}
// 获取成绩分布
getGradeDistribution() {
const distribution = {
'A': 0, // 90-100
'B': 0, // 80-89
'C': 0, // 70-79
'D': 0, // 60-69
'F': 0 // 0-59
};
for (let i = 0; i < this.students.length; i++) {
const score = this.students[i].score;
if (score >= 90) {
distribution['A']++;
} else if (score >= 80) {
distribution['B']++;
} else if (score >= 70) {
distribution['C']++;
} else if (score >= 60) {
distribution['D']++;
} else {
distribution['F']++;
}
}
return distribution;
}
}
// 测试
const system = new StudentGradeSystem();
system.addStudent('张三', 85);
system.addStudent('李四', 92);
system.addStudent('王五', 78);
system.addStudent('赵六', 65);
system.addStudent('钱七', 45);
console.log('平均分:', system.calculateAverage()); // 73
console.log('成绩范围:', system.findScoreRange());
console.log('成绩分布:', system.getGradeDistribution());
2. 购物车功能实现
// 练习10:购物车管理系统
class ShoppingCart {
constructor() {
this.items = [];
}
// 添加商品
addItem(name, price, quantity = 1) {
// 检查是否已存在相同商品
for (let i = 0; i < this.items.length; i++) {
if (this.items[i].name === name) {
this.items[i].quantity += quantity;
return;
}
}
// 新商品
this.items.push({
name,
price,
quantity
});
}
// 移除商品
removeItem(name, quantity = 1) {
for (let i = 0; i < this.items.length; i++) {
if (this.items[i].name === name) {
if (this.items[i].quantity <= quantity) {
// 移除整个商品
this.items.splice(i, 1);
} else {
// 减少数量
this.items[i].quantity -= quantity;
}
break;
}
}
}
// 计算总价
calculateTotal() {
let total = 0;
for (let i = 0; i < this.items.length; i++) {
total += this.items[i].price * this.items[i].quantity;
}
return total;
}
// 应用折扣
applyDiscount(discountPercent) {
if (discountPercent < 0 || discountPercent > 100) {
console.error('折扣比例必须在0-100之间');
return;
}
const discount = this.calculateTotal() * (discountPercent / 100);
return this.calculateTotal() - discount;
}
// 清空购物车
clearCart() {
this.items = [];
}
// 显示购物车内容
showCart() {
if (this.items.length === 0) {
console.log('购物车为空');
return;
}
console.log('购物车内容:');
for (let i = 0; i < this.items.length; i++) {
const item = this.items[i];
console.log(`${item.name} - 单价: ¥${item.price} × ${item.quantity} = ¥${item.price * item.quantity}`);
}
console.log(`总计: ¥${this.calculateTotal()}`);
}
}
// 测试
const cart = new ShoppingCart();
cart.addItem('苹果', 5, 3);
cart.addItem('香蕉', 3, 2);
cart.addItem('橙子', 4, 1);
cart.addItem('苹果', 5, 2); // 增加苹果数量
cart.showCart();
console.log('总价:', cart.calculateTotal());
console.log('8折后价格:', cart.applyDiscount(20));
cart.removeItem('香蕉', 1);
cart.showCart();
四、挑战练习
1. 数组去重与排序组合
// 练习11:数组去重并排序
function uniqueAndSort(arr) {
// 方法1:使用Set和sort
// return [...new Set(arr)].sort((a, b) => a - b);
// 方法2:手动实现(不使用Set)
const uniqueArr = [];
for (let i = 0; i < arr.length; i++) {
let isDuplicate = false;
// 检查是否已存在
for (let j = 0; j < uniqueArr.length; j++) {
if (arr[i] === uniqueArr[j]) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
uniqueArr.push(arr[i]);
}
}
// 冒泡排序
for (let i = 0; i < uniqueArr.length - 1; i++) {
for (let j = 0; j < uniqueArr.length - 1 - i; j++) {
if (uniqueArr[j] > uniqueArr[j + 1]) {
const temp = uniqueArr[j];
uniqueArr[j] = uniqueArr[j + 1];
uniqueArr[j + 1] = temp;
}
}
}
return uniqueArr;
}
// 测试
console.log(uniqueAndSort([3, 1, 2, 3, 4, 2, 5, 1])); // [1, 2, 3, 4, 5]
2. 矩阵操作
// 练习12:矩阵转置
function transposeMatrix(matrix) {
if (matrix.length === 0) return [];
const rows = matrix.length;
const cols = matrix[0].length;
const result = [];
// 初始化结果矩阵
for (let i = 0; i < cols; i++) {
result[i] = new Array(rows);
}
// 转置
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
result[j][i] = matrix[i][j];
}
}
return result;
}
// 测试
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
console.log('原矩阵:');
matrix.forEach(row => console.log(row));
console.log('转置后:');
transposeMatrix(matrix).forEach(row => console.log(row));
五、综合项目实战
待办事项列表应用
// 练习13:待办事项管理系统
class TodoList {
constructor() {
this.todos = [];
this.nextId = 1;
}
// 添加待办事项
addTodo(task, priority = 'medium') {
const validPriorities = ['low', 'medium', 'high'];
if (!validPriorities.includes(priority)) {
priority = 'medium';
}
this.todos.push({
id: this.nextId++,
task,
priority,
completed: false,
createdAt: new Date()
});
}
// 标记为完成
markAsCompleted(id) {
for (let i = 0; i < this.todos.length; i++) {
if (this.todos[i].id === id) {
this.todos[i].completed = true;
break;
}
}
}
// 删除待办事项
deleteTodo(id) {
for (let i = 0; i < this.todos.length; i++) {
if (this.todos[i].id === id) {
this.todos.splice(i, 1);
break;
}
}
}
// 获取所有待办事项
getAllTodos() {
return [...this.todos];
}
// 按优先级筛选
getTodosByPriority(priority) {
const filtered = [];
for (let i = 0; i < this.todos.length; i++) {
if (this.todos[i].priority === priority) {
filtered.push(this.todos[i]);
}
}
return filtered;
}
// 获取未完成的待办事项
getPendingTodos() {
const pending = [];
for (let i = 0; i < this.todos.length; i++) {
if (!this.todos[i].completed) {
pending.push(this.todos[i]);
}
}
return pending;
}
// 统计信息
getStats() {
const total = this.todos.length;
let completed = 0;
let highPriority = 0;
for (let i = 0; i < this.todos.length; i++) {
if (this.todos[i].completed) completed++;
if (this.todos[i].priority === 'high') highPriority++;
}
return {
total,
completed,
pending: total - completed,
highPriority,
completionRate: total > 0 ? (completed / total * 100).toFixed(2) + '%' : '0%'
};
}
// 显示待办事项
displayTodos() {
if (this.todos.length === 0) {
console.log('没有待办事项');
return;
}
console.log('待办事项列表:');
for (let i = 0; i < this.todos.length; i++) {
const todo = this.todos[i];
const status = todo.completed ? '✓' : '○';
console.log(`${status} [${todo.priority.toUpperCase()}] ${todo.id}. ${todo.task}`);
}
}
}
// 测试
const todoList = new TodoList();
todoList.addTodo('学习JavaScript', 'high');
todoList.addTodo('购买 groceries', 'medium');
todoList.addTodo('看电影', 'low');
todoList.addTodo('完成项目报告', 'high');
todoList.displayTodos();
console.log('统计:', todoList.getStats());
todoList.markAsCompleted(1);
todoList.markAsCompleted(4);
console.log('\n完成任务后:');
todoList.displayTodos();
console.log('统计:', todoList.getStats());
console.log('\n高优先级任务:');
console.log(todoList.getTodosByPriority('high'));
练习指导
学习要点:
数组遍历:for循环、forEach、for...of
条件判断:if-else、switch、三元运算符
数组方法:push、pop、shift、unshift、splice、slice
循环控制:break、continue、return
算法思维:排序、搜索、统计、转换
建议练习顺序:
先完成基础练习,确保理解基本语法
尝试中级练习,掌握数组常用操作
挑战高级案例,培养解决问题能力
尝试自己修改和扩展案例功能
扩展练习:
为每个案例添加错误处理
将函数式编程方法(map、filter、reduce)应用于这些案例
创建图形界面来展示这些功能
将数据保存到localStorage实现持久化
通过这些练习,你将掌握JavaScript中流程控制和数组操作的核心技能,为更复杂的应用开发打下坚实基础。