为何无法循环执行彩票号码统计函数?
彩票号码统计函数循环调用出错原因分析
问题场景
实现了一个统计彩票号码出现次数的JavaScript函数:通过fs.readFileSync读取dados.txt数据并分割为数组,vezSort函数单独调用时可正常统计指定号码的出现次数,但尝试循环调用该函数统计1-60号时,conteudo[i] = conteudo[i].split(";");行出现错误。
原代码如下:
//Transfer the txt logs to variable 'conteudo' try { conteudo = fs.readFileSync("dados.txt", "utf8"); conteudo = conteudo.split("\r\n"); vezessort = 0; } catch(erro) { console.error(erro.message); } //Function created to review all the lines in the txt file //First for loop is to split each line, making them an array //Second loop is to compare the values 2 to 7 on each line, where contains the numbers drawn in the lottery function vezSort(a){ for (i = 1; i < conteudo.length; i++){ conteudo[i] = conteudo[i].split(";"); for(j = 2; j < 8; j++){ if(conteudo[i][j] == a){ vezessort += 1; } } } } //In this exercise we need to capture the input from user, and use it as a parameter on the function a = parseInt(prompt('Digite um número: ')); r = vezSort(a); console.log(`O número foi sorteado ${vezessort} vezes.`);
注:当前需求无需用户输入,只需循环统计1-60号。
错误原因
- 重复修改原数组导致类型错误:第一次调用
vezSort时,conteudo[i]会被从字符串转为数组(执行split(";"))。当第二次循环调用函数时,conteudo[i]已经是数组类型,再调用数组的split方法就会报错——因为数组对象没有split方法,只有字符串才有。 - 全局变量累加错误:
vezessort是全局变量,每次调用vezSort时不会重置为0,导致后续号码的统计结果会累加之前的统计值,结果完全错误。
修复方案
方案1:提前一次性分割所有行,避免重复处理
先把所有行一次性分割为二维数组,后续函数直接使用处理好的数组,无需重复分割:
const fs = require('fs'); let conteudo; try { conteudo = fs.readFileSync("dados.txt", "utf8"); // 提前分割所有行并处理成二维数组,过滤空行 conteudo = conteudo.split("\r\n").filter(line => line.trim()).map(line => line.split(";")); } catch(erro) { console.error(erro.message); } function vezSort(num) { let count = 0; // 从索引1开始遍历(跳过表头行) for (let i = 1; i < conteudo.length; i++) { // 直接使用已分割好的数组 for(let j = 2; j < 8; j++){ if(conteudo[i][j] == num){ count += 1; } } } return count; } // 循环统计1-60号 for(let num = 1; num <= 60; num++) { const times = vezSort(num); console.log(`O número ${num} foi sorteado ${times} vezes.`); }
方案2:函数内部不修改原数组,临时处理每行
如果不想提前修改原数组,在函数内部每次处理时先临时转换:
const fs = require('fs'); let conteudo; try { conteudo = fs.readFileSync("dados.txt", "utf8"); conteudo = conteudo.split("\r\n").filter(line => line.trim()); } catch(erro) { console.error(erro.message); } function vezSort(num) { let count = 0; for (let i = 1; i < conteudo.length; i++) { // 临时分割当前行,不修改原数组 const lineArr = conteudo[i].split(";"); for(let j = 2; j < 8; j++){ if(lineArr[j] == num){ count += 1; } } } return count; } // 循环统计1-60号 for(let num = 1; num <= 60; num++) { const times = vezSort(num); console.log(`O número ${num} foi sorteado ${times} vezes.`); }
关键优化点
- 使用局部变量
count替代全局变量vezessort,每次调用函数都会重置计数,避免累加错误。 - 避免重复修改原数组,要么提前一次性处理完成,要么在函数内部临时处理每行,不改变原数组的结构。
- 增加空行过滤(
filter(line => line.trim())),避免处理文件末尾的空行导致错误。
内容的提问来源于stack exchange,提问作者Marcos Vinicius
相关产品推荐
相关产品推荐

