5_TypeScript 循环 --[深入浅出 TypeScript 测试]

news2025/1/8 17:40:03

在 TypeScript 中,循环结构与 JavaScript 相同,因为 TypeScript 是 JavaScript 的一个超集。TypeScript 添加了静态类型检查和其他一些特性,但它保留了 JavaScript 的所有语法和功能,包括循环。

以下是几种常见的循环结构:

for 循环

for (let i = 0; i < 5; i++) {
    console.log(i);
}

下面是两个使用 for 循环的具体示例,展示了如何在 TypeScript 中使用它来进行不同的任务:

示例 1: 计算数组元素的总和

假设我们有一个包含数字的数组,并且想要计算这些数字的总和。我们可以使用 for 循环来遍历数组并累加每个元素。

function sumArrayElements(arr: number[]): number {
    let total: number = 0;
    for (let i: number = 0; i < arr.length; i++) {
        total += arr[i];
    }
    return total;
}

// 使用示例
const numbers: number[] = [1, 2, 3, 4, 5];
console.log("数组元素的总和是: " + sumArrayElements(numbers)); // 输出:数组元素的总和是: 15

示例 2: 打印乘法表

这个例子展示了一个简单的 for 循环嵌套,用于打印一个给定数字的乘法表(例如9x9乘法表)。

function printMultiplicationTable(n: number): void {
    for (let i: number = 1; i <= n; i++) {
        let row: string = '';
        for (let j: number = 1; j <= n; j++) {
            row += `${i}*${j}=${i * j}\t`; // 使用制表符\t来分隔每一项
        }
        console.log(row);
    }
}

// 使用示例
printMultiplicationTable(9); // 打印9x9乘法表

在这两个示例中,for 循环都被用来迭代一组值或执行一系列操作。第一个示例是一个简单的累加过程,而第二个示例则涉及到了循环的嵌套,以创建更复杂的输出结构。这两个例子也展示了如何在 TypeScript 中为变量添加类型注解,确保代码的类型安全性和可读性。

while 循环

let i = 0;
while (i < 5) {
    console.log(i);
    i++;
}

下面是两个使用 while 循环的具体示例,展示了如何在 TypeScript 中利用 while 循环来完成不同的任务:

示例 1: 计算斐波那契数列

假设我们想要生成一个包含前 n 个斐波那契数的数组。我们可以使用 while 循环来构建这个序列。

function generateFibonacci(n: number): number[] {
    let fib: number[] = [];
    let a: number = 0, b: number = 1;
    while (fib.length < n) {
        fib.push(a);
        [a, b] = [b, a + b]; // 使用解构赋值更新 a 和 b
    }
    return fib;
}

// 使用示例
const numElements: number = 10;
console.log(`${numElements} 个斐波那契数是: ${generateFibonacci(numElements).join(', ')}`);
// 输出:前 10 个斐波那契数是: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

示例 2: 模拟猜数字游戏

在这个例子中,我们将创建一个简单的猜数字游戏。计算机随机选择一个介于 1 到 100 之间的数字,玩家需要猜测这个数字是什么。程序会提示玩家输入他们的猜测,并告诉他们猜得太高、太低还是正确,直到他们猜对为止。

function guessTheNumber(): void {
    const targetNumber: number = Math.floor(Math.random() * 100) + 1; // 随机生成1到100之间的整数
    let guess: number | null = null;

    console.log("欢迎来到猜数字游戏!我已经想好了一个1到100之间的数字。");

    while (guess !== targetNumber) {
        guess = parseInt(prompt("请输入你的猜测:") || "0", 10); // 假设有一个prompt函数获取用户输入
        if (isNaN(guess)) {
            console.log("请输入一个有效的数字!");
            continue;
        }

        if (guess < targetNumber) {
            console.log("太低了,请再试一次。");
        } else if (guess > targetNumber) {
            console.log("太高了,请再试一次。");
        } else {
            console.log("恭喜你,猜对了!");
        }
    }
}

// 注意:在实际浏览器环境中,可以使用 window.prompt 来获取用户输入。
// 在Node.js或没有UI的环境中,您可能需要用其他方式(如命令行参数或读取文件)来模拟用户输入。
// 使用示例(此代码段需要适应具体的执行环境)
// guessTheNumber();

请注意,在第二个示例中,prompt 函数用于获取用户的输入。这在浏览器环境中是可用的,但在 Node.js 环境中则不可用。如果你是在非浏览器环境中运行这段代码,你需要找到一种适合该环境的方法来接收用户输入,比如使用命令行界面(CLI)工具或者模拟用户输入。

这两个例子展示了 while 循环的灵活性以及它在不知道循环次数的情况下进行迭代的能力。第一个例子是一个计算问题,而第二个例子则涉及到用户交互和条件判断。

do…while 循环

let i = 0;
do {
    console.log(i);
    i++;
} while (i < 5);

当然,do...while 循环在 TypeScript 中至少执行一次循环体中的代码,然后根据条件判断是否继续执行。下面提供了两个使用 do...while 循环的具体示例:

示例 1: 用户输入验证

假设我们想要创建一个简单的程序来确保用户输入的是一个有效的正整数。我们可以使用 do...while 循环来不断请求用户输入,直到他们提供了一个有效的数字。

function getUserInput(): number {
    let userInput: string | null;
    let num: number;

    do {
        userInput = prompt("请输入一个正整数:") || "0"; // 假设有一个prompt函数获取用户输入
        num = parseInt(userInput, 10);

        if (isNaN(num) || num <= 0) {
            console.log("输入无效,请输入一个正整数!");
        }
    } while (isNaN(num) || num <= 0);

    return num;
}

// 注意:在实际浏览器环境中,可以使用 window.prompt 来获取用户输入。
// 在Node.js或没有UI的环境中,您可能需要用其他方式(如命令行参数或读取文件)来模拟用户输入。
// 使用示例(此代码段需要适应具体的执行环境)
// const validNumber = getUserInput();
// console.log(`你输入的有效正整数是: ${validNumber}`);

示例 2: 简单的猜硬币游戏

在这个例子中,我们将创建一个简单的猜硬币游戏。计算机随机选择“正面”或“反面”,玩家猜测结果。无论第一次猜测是否正确,游戏都会让玩家至少玩一次,并且只有在玩家决定停止时才会结束。

function coinFlipGame(): void {
    const outcomes: string[] = ['正面', '反面'];
    let playAgain: boolean = true;

    do {
        const flipResult: string = outcomes[Math.floor(Math.random() * outcomes.length)];
        const userGuess: string = prompt("请猜一猜,硬币是'正面'还是'反面'?")?.trim().toLowerCase() || '';

        if (userGuess === flipResult) {
            console.log(`恭喜你!你猜对了,是${flipResult}`);
        } else {
            console.log(`很遗憾,这次是${flipResult}`);
        }

        // 检查用户是否想再次玩游戏
        const again: string = prompt("你想再玩一次吗?(yes/no)")?.trim().toLowerCase() || '';
        playAgain = again === 'yes';
    } while (playAgain);
}

// 注意:在实际浏览器环境中,可以使用 window.prompt 来获取用户输入。
// 在Node.js或没有UI的环境中,您可能需要用其他方式(如命令行参数或读取文件)来模拟用户输入。
// 使用示例(此代码段需要适应具体的执行环境)
// coinFlipGame();

这两个例子展示了 do...while 循环的特点,即它会保证循环体至少被执行一次,这对于那些需要至少执行一次操作然后再检查条件的场景非常有用。第一个例子用于确保用户输入有效数据,而第二个例子则用于创建一个简单但有趣的游戏体验。

for…in 循环

for...in 循环用于遍历对象的可枚举属性(包括从原型链继承的属性)。对于数组来说,它会迭代索引。

const obj = { a: 1, b: 2, c: 3 };
for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(`${key}: ${obj[key]}`);
    }
}

for...in 循环在 TypeScript 中用于遍历对象的可枚举属性。它会迭代对象自身以及从原型链继承的所有可枚举属性,因此在使用时需要注意这一点。下面提供了两个使用 for...in 循环的具体示例:

示例 1: 遍历对象的属性

假设我们有一个表示学生的对象,其中包含一些个人信息。我们可以使用 for...in 循环来遍历这个对象,并打印出每个属性及其对应的值。

const student = {
    name: "张三",
    age: 20,
    major: "计算机科学"
};

for (const key in student) {
    if (student.hasOwnProperty(key)) { // 确保只处理对象自身的属性
        console.log(`${key}: ${student[key]}`);
    }
}

// 输出:
// name: 张三
// age: 20
// major: 计算机科学

示例 2: 遍历数组索引(不推荐)

虽然 for...in 可以用来遍历数组的索引,但这是不推荐的做法,因为 for...in 也会遍历原型链上的可枚举属性,这可能导致意外的结果。更好的做法是使用 for...of 或传统的 for 循环。然而,为了展示如何用 for...in 遍历数组,这里提供一个例子:

const numbers = [10, 20, 30, 40, 50];

for (const index in numbers) {
    if (numbers.hasOwnProperty(index)) { // 确保只处理数组自身的属性
        console.log(`Index ${index}: Value ${numbers[index]}`);
    }
}

// 输出:
// Index 0: Value 10
// Index 1: Value 20
// Index 2: Value 30
// Index 3: Value 40
// Index 4: Value 50

请注意,在遍历对象或数组时,总是要检查 hasOwnProperty 方法来确保你只处理对象自身的属性,而不是那些通过原型链继承来的属性。对于数组来说,通常更推荐使用 for...of 或者普通的 for 循环来遍历元素,因为它们更加直观且不会受到原型链的影响。

如果你确实需要遍历对象的属性,for...in 是一个很好的选择,但是在遍历数组时应谨慎使用,避免潜在的问题。

for…of 循环

for...of 循环是 ES6 引入的新特性,它用来遍历可迭代对象(如数组、字符串、Map、Set 等)的值。

const arr = [10, 20, 30];
for (const value of arr) {
    console.log(value);
}

for...of 循环是 ES6 引入的一种遍历可迭代对象(如数组、字符串、Map、Set 等)的值的方法。它非常适合于那些只需要访问元素本身而不需要索引的情况。下面是两个使用 for...of 循环的具体示例:

示例 1: 遍历数组并计算平均数

假设我们有一个包含学生成绩的数组,并且想要计算这些成绩的平均分。我们可以使用 for...of 循环来遍历数组中的每个成绩,并计算总和,最后求出平均分。

function calculateAverage(scores: number[]): number {
    let sum: number = 0;
    for (const score of scores) {
        sum += score;
    }
    return scores.length > 0 ? sum / scores.length : 0;
}

// 使用示例
const studentScores: number[] = [88, 92, 75, 83, 90];
console.log(`学生的平均成绩是: ${calculateAverage(studentScores).toFixed(2)}`);
// 输出:学生的平均成绩是: 85.60

示例 2: 遍历字符串并统计字符出现次数

在这个例子中,我们将创建一个函数来遍历一个字符串,并统计每个字符出现的次数。这可以用来分析文本中字符的频率。

function countCharacters(str: string): {[key: string]: number} {
    const charCount: {[key: string]: number} = {};
    for (const char of str) {
        if (char in charCount) {
            charCount[char]++;
        } else {
            charCount[char] = 1;
        }
    }
    return charCount;
}

// 使用示例
const text: string = "hello world";
const characterCounts = countCharacters(text);
console.log(characterCounts);
// 输出:{ h: 1, e: 1, l: 3, o: 2, ' ': 1, w: 1, r: 1, d: 1 }

在这两个示例中,for...of 循环被用于遍历不同的数据结构(数组和字符串),并且展示了如何在 TypeScript 中处理这些数据。第一个示例演示了如何对数值进行累加以计算平均值,而第二个示例则展示了如何遍历字符串并对字符计数。这两个例子都体现了 for...of 循环简洁明了的特点,尤其是在你需要直接操作集合中的元素时。

forEach 方法(针对数组)

这不是语言层面的循环结构,而是数组的一个方法,它可以更简洁地遍历数组元素。

const arr = [1, 2, 3];
arr.forEach((value, index, array) => {
    console.log(`Element at index ${index} is ${value}`);
});

forEach 方法是 JavaScript 数组的一个内置方法,它允许你为数组中的每个元素执行一次提供的函数。这个方法非常适合用来遍历数组并对其元素进行操作。在 TypeScript 中使用 forEach 时,你可以利用类型注解来确保代码的类型安全性和可读性。以下是两个具体的示例:

示例 1: 使用 forEach 打印数组元素

假设我们有一个包含学生名字的字符串数组,并且想要打印出每个学生的欢迎信息。

const students: string[] = ["Alice", "Bob", "Charlie"];

students.forEach((student) => {
    console.log(`欢迎, ${student}!`);
});

// 输出:
// 欢迎, Alice!
// 欢迎, Bob!
// 欢迎, Charlie!

在这个例子中,forEach 方法接收一个回调函数作为参数,该回调函数会在数组的每一个元素上被调用。回调函数接收当前元素(这里是 student)作为其参数,并可以对其进行任意操作。

示例 2: 使用 forEach 对数组元素进行累加

在这个例子中,我们将创建一个函数来计算一个数字数组中所有元素的总和。虽然通常我们会使用 reduce 方法来做这种累加操作,但这里我们展示如何使用 forEach 来实现相同的功能。

function sumArrayElements(arr: number[]): number {
    let total: number = 0;

    arr.forEach((value) => {
        total += value;
    });

    return total;
}

// 使用示例
const numbers: number[] = [1, 2, 3, 4, 5];
console.log(`数组元素的总和是: ${sumArrayElements(numbers)}`);
// 输出:数组元素的总和是: 15

在这个例子中,forEach 同样接收一个回调函数,这次我们还定义了一个累加器变量 total 来保存累加的结果。每当 forEach 调用回调函数时,它会将当前元素的值加到 total 上。

这两个例子展示了 forEach 方法的灵活性以及它是如何与 TypeScript 的类型系统一起工作的。第一个例子简单地遍历了数组并打印了信息,而第二个例子则展示了如何使用 forEach 来累积数组元素的值。请注意,forEach 不会改变原始数组,并且它的主要用途是在不改变数组的情况下对数组元素执行某些操作。

使用类型注解

在 TypeScript 中,你可以为循环变量添加类型注解,以确保类型安全。

for (let i: number = 0; i < 5; i++) {
    console.log(i);
}

const obj = { a: 'one', b: 'two', c: 'three' };
for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(`${key}: ${(obj as {[key: string]: string})[key]}`);
    }
}

const arr = [1, 2, 3];
arr.forEach((value: number, index: number, array: number[]) => {
    console.log(`Element at index ${index} is ${value}`);
});

选择哪种循环取决于你的具体需求以及你想要操作的数据类型。例如,如果你需要遍历数组并且不需要改变数组本身,那么 for...offorEach 可能是最合适的选择。如果你需要遍历对象的属性,那么 for...in 就很有用。而传统的 forwhile 循环则适用于更广泛的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2272749.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

B树与B+树:数据库索引的秘密武器

想象一下&#xff0c;你正在构建一个超级大的图书馆&#xff0c;里面摆满了各种各样的书籍。B树和B树就像是两种不同的图书分类和摆放方式&#xff0c;它们都能帮助你快速找到想要的书籍&#xff0c;但各有特点。 B树就像是一个传统的图书馆摆放方式&#xff1a; 1. 书籍摆放&…

回归预测 | MATLAB实现CNN-SVM多输入单输出回归预测

回归预测 | MATLAB实现CNN-SVM多输入单输出回归预测 目录 回归预测 | MATLAB实现CNN-SVM多输入单输出回归预测预测效果基本介绍模型架构程序设计参考资料 预测效果 基本介绍 CNN-SVM多输入单输出回归预测是一种结合卷积神经网络&#xff08;CNN&#xff09;和支持向量机&#…

Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度

Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度 一&#xff0c; PWM实现原理二&#xff0c;软件实现三&#xff0c;正点原子裸机开发总结 一&#xff0c; PWM实现原理 PWM和学习51时候基本上一致&#xff0c;控制频率&#xff08;周期&#xff09;和占空比&#xff0c;51实验…

自定义校验注解

已有的注解不能满足所有的校验需求,特殊的情况需要自定义校验(自定义校验注解) 1.自定义注解,并在注解上指定校验逻辑 Constraint(validatedBy StateValidation.class) // 指定校验逻辑 package com.example.demo.validation;import jakarta.validation.Constraint; import j…

分数阶傅里叶变换代码 MATLAB实现

function Faf myfrft(f, a) %分数阶傅里叶变换函数 %输入参数&#xff1a; %f&#xff1a;原始信号 %a&#xff1a;阶数 %输出结果&#xff1a; %原始信号的a阶傅里叶变换N length(f);%总采样点数 shft rem((0:N-1)fix(N/2),N)1;%此项等同于fftshift(1:N)&#xff0c;起到翻…

Ubuntu 20.04安装gcc

一、安装GCC 1.更新包列表 user596785154:~$ sudo apt update2.安装gcc user596785154:~$ sudo apt install gcc3.验证安装 user596785154:~$ gcc --version二 编译C文件 1.新建workspace文件夹 user596785154:~$ mkdir workspace2.进入workspace文件夹 user596785154:~…

小兔鲜儿:头部区域的logo,导航,搜索,购物车

头部&#xff1a;logo ,导航&#xff0c;搜索&#xff0c;购物车 头部总体布局: 设置好上下外边距以及总体高度&#xff0c; flex布局让总体一行排列 logo&#xff1a; logo考虑搜索引擎优化&#xff0c;所以要使用 h1中包裹 a 标签&#xff0c;a 里边写内容&#xff08;到时候…

Linux C编程——文件IO基础

文件IO基础 一、简单的文件 IO 示例二、文件描述符三、open 打开文件1. 函数原型2. 文件权限3. 宏定义文件权限4. 函数使用实例 四、write 写文件五、read 读文件六、close 关闭文件七、Iseek 绍 Linux 应用编程中最基础的知识&#xff0c;即文件 I/O&#xff08;Input、Outout…

论文解读 | NeurIPS'24 IRCAN:通过识别和重新加权上下文感知神经元来减轻大语言模型生成中的知识冲突...

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 史丹&#xff0c;天津大学博士生 内容简介 大语言模型&#xff08;LLM&#xff09;经过海量数据训练后编码了丰富的世界知识。最近的研究表明&#xff0c…

【51单片机零基础-chapter5:模块化编程】

模块化编程 将以往main中泛型的代码,放在与main平级的c文件中,在h中引用. 简化main函数 将原来main中的delay抽出 然后将delay放入单独c文件,并单独开一个delay头文件,里面放置函数的声明,相当于收纳delay的c文件里面写的函数的接口. 注意,单个c文件所有用到的变量需要在该文…

扩散模型论文概述(三):Stability AI系列工作【学习笔记】

视频链接&#xff1a;扩散模型论文概述&#xff08;三&#xff09;&#xff1a;Stability AI系列工作_哔哩哔哩_bilibili 本期视频讲的是Stability AI在图像生成的工作。 同样&#xff0c;第一张图片是神作&#xff0c;总结的太好了&#xff01; 介绍Stable Diffusion之前&…

数据库软考历年上午真题与答案解析(2018-2024)

本题考查计算机总线相关知识。 总线&#xff08;Bus&#xff09;是计算机各种功能部件之间传送信息的公共通信干线&#xff0c;它是由导线组成的传输线束。 根据总线连接设备范围的不同&#xff0c; 分为&#xff1a;1.片内总线&#xff1a;芯片内部的总线&#xff1b; 2.系统…

【three.js】模型-几何体Geometry,材质Material

模型 在现实开发中&#xff0c;有时除了需要用代码创建模型之外&#xff0c;多数场景需要加载设计师提供的使用设计软件导出的模型。此时就需要使用模型加载器去加载模型&#xff0c;不同格式的模型需要引入对应的模型加载器&#xff0c;虽然加载器不同&#xff0c;但是使用方式…

彻底学会Gradle插件版本和Gradle版本及对应关系

看完这篇&#xff0c;保你彻底学会Gradle插件版本和Gradle版本及对应关系&#xff0c;超详细超全的对应关系表 需要知道Gradle插件版本和Gradle版本的对应关系&#xff0c;其实就是需要知道Gradle插件版本对应所需的gradle最低版本&#xff0c;详细对应关系如下表格&#xff0…

预测facebook签到位置

1.11 案例2&#xff1a;预测facebook签到位置 学习目标 目标 通过Facebook位置预测案例熟练掌握第一章学习内容 1 项目描述 本次比赛的目的是预测一个人将要签到的地方。 为了本次比赛&#xff0c;Facebook创建了一个虚拟世界&#xff0c;其中包括10公里*10公里共100平方公里的…

【万字详细教程】Linux to go——装在移动硬盘里的Linux系统(Ubuntu22.04)制作流程;一口气解决系统安装引导文件迁移显卡驱动安装等问题

Linux to go制作流程 0.写在前面 关于教程Why Linux to go&#xff1f;实际效果 1.准备工具2.制作步骤 下载系统镜像硬盘分区准备启动U盘安装系统重启完成驱动安装将系统启动引导程序迁移到移动硬盘上 3.可能出现的问题 3.1.U盘引导系统安装时出现崩溃3.2.不影响硬盘里本身已有…

在 macOS 上,你可以使用系统自带的 终端(Terminal) 工具,通过 SSH 协议远程连接服务器

文章目录 1. 打开终端2. 使用 SSH 命令连接服务器3. 输入密码4. 连接成功5. 使用密钥登录&#xff08;可选&#xff09;6. 退出 SSH 连接7. 其他常用 SSH 选项8. 常见问题排查问题 1&#xff1a;连接超时问题 2&#xff1a;权限被拒绝&#xff08;Permission denied&#xff09…

Linux CentOS 7系统如何修改panel 重新打开最小化的界面/软件/程序

CentOS 7系统下&#xff0c;部分用户可能一开始打开界面没有类似Windows的下方菜单栏&#xff0c;只有一个浮动的panel。一旦打开软件&#xff0c;然后点击最小化后&#xff0c;找不到重新打开的方法。 右键panel&#xff0c;点击Add New Items… 选择以下三个基本就可以了&am…

打造三甲医院人工智能矩阵新引擎(二):医学影像大模型篇--“火眼金睛”TransUNet

一、引言 1.1 研究背景与意义 在现代医疗领域,医学影像作为疾病诊断与治疗的关键依据,发挥着不可替代的作用。从传统的X射线、CT(计算机断层扫描)到MRI(磁共振成像)等先进技术,医学影像能够直观呈现人体内部结构,为医生提供丰富的诊断信息,涵盖疾病识别、病灶定位、…

基于Arduino的FPV头部追踪相机系统

构建FPV头部追踪相机&#xff1a;让你置身于遥控车辆之中&#xff01; 在遥控车辆和模型飞行器的世界中&#xff0c;第一人称视角&#xff08;FPV&#xff09;体验一直是爱好者们追求的目标。通过FPV头部追踪相机&#xff0c;你可以像坐在车辆或飞行器内部一样&#xff0c;自由…