有关迭代器Iterator、Set、Map集合、数值扩展、async异步函数的知识点

目录

一、迭代器Iterator

1.1.概念

1.2.作用

1.3Iterator 的遍历过程

2.Set

2.1概念

3.Map集合

3.1概念

3.2map和object区别?

4.数据扩展

4.1 Number.isFinite(), Number.isNaN()

4.2 Number.parseInt(), Number.parseFloat()

4.3 Number.isInteger()

5. async异步函数

5.1概念


一、迭代器Iterator

1.1.概念

迭代器 (Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator 接口,就可以访问容器中的元素,也可以完成遍历操作。

1.2.作用

  1. 为各种数据结构,提供一个统一的、简便的访问接口;
  2. 它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。
  3. 使数据结构的成员能够按某种次序排列;
  4. ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。

例如,如果没有使用Iterator,遍历一个数组的方法是使用索引

for(let i=0; i<arr.length; i++) {  }

而访问一个链表(LinkedList)又必须使用while循环:

while((arr=arr.next())!=null) { ... arr.data() ... }

1.3Iterator 的遍历过程

  1. 创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

  2. 第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

  3. 第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

  4. 不断调用指针对象的next方法,直到它指向数据结构的结束位置。

1.迭代器实现了Iterator接口,只要有实现了Iterator就可以使用for-of遍历
let arr=[1,2,3,4,5];
console.log(arr.keys()); //Object [Array Iterator] {}
console.log(arr.values());  //Object [Array Iterator] {}
console.log(arr.entries());  //Object [Array Iterator] {}

 

 let [a] = '10'; //字符串实现了迭代器接口 就可以使用for ...of遍历
 console.log(a); //1
 let [a, b] = '10'; //[ '1', '0' ]
 let [a,b]=10; //报错10 is not iterable
 console.log([a, b]); 

let str='hello'; //实现了迭代器接口,可以遍历
for(let key of str){
    console.log(key); //h e l l o
}


// 以前遍历字符串
let [...a]=str;
console.log(a); //[ 'h', 'e', 'l', 'l', 'o' ]
let result=str.split("")
console.log(result);  //[ 'h', 'e', 'l', 'l', 'o' ]
for(i=0;i<str.length;i++){
    console.log(str.charAt(i));  //h e l l o
}

//遍历迭代器对象
let arr=[1,2,3,4,5];
let keys=arr.keys();
for(let key of keys){
    console.log(key); //0 1 2 3 4
}

let values=arr.values();
for(let value of values){
    console.log(value); // 1 2 3 4 5
}

let entries=arr.entries();
for(let entry of entries){
    console.log(entry); [ 0, 1 ][ 1, 2 ][ 2, 3 ][ 3, 4 ][ 4, 5 ]
}

for-of实现原理:调用迭代器的next()方法,第一次调用将指针指向数据结构的第一个成员,依次调用依次指向,直到没有成员可以指向,done为true则代表没有成员可遍历了。

  • 迭代过程:创建一个指针对象,指向当前的数据结构起始位置;
  • 第一次调用指针对象的next方法,指向数据结构的第一个成员;
  • 第二次调用指针对象的next方法,指向数据结构的第二个成员;
  • 直到done为true,指向数据结构的结束位置;
let arr = [1, 2, 3, 'hello'];
let values = arr.values();
let result;
while (!(result = values.next()).done) {
    console.log(result); 
    //{ value: 1, done: false }
    //{ value: 2, done: false }
    //{ value: 3, done: false }
    //{ value: 'hello', done: false }
}

let arr = [1];
let keys = arr.keys();
let values = arr.values();
let entries = arr.entries()
console.log(keys.next()); //{ value: 0, done: false }
console.log(keys.next()); //{ value: undefined, done: true }
console.log(values.next()); //{ value: 1, done: false }
console.log(values.next());//{ value: undefined, done: true }
console.log(entries.next());//{ value: [ 0, 1 ], done: false }
console.log(entries.next()); //{ value: undefined, done: true }

原生具备 Iterator 接口的数据结构如下:
 Array、Map、Set、String、TypedArray、arguments、NodeList

 

2.Set

2.1概念

Set类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构。Set 构造函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。

var set=new Set()
//创建Set集合 成员是唯一的,key-value是一样的
//添加元素
set.add('hello');
set.add('world');
set.add('world');
console.log(set);  //Set(2) { 'hello', 'world' }
// 删除元素
set.delete('hello');  
console.log(set);   Set(1) { 'world' }
// 遍历
let keys=set.keys()  //[Set Iterator] { 'hello', 'world' }
let values=set.values()  //[Set Iterator] { 'hello', 'world' }
let entries=set.entries(); //[Set Entries] { [ 'hello', 'hello' ], [ 'world', 'world' ] }
console.log(keys,values,entries);
set.forEach((value)=>{
    console.log(value); //hello world
})
//判断有没有某个成员
set.has('hello');返回布尔值true或者false,有返回true,没有返回false
//清空set
set.clear();  //Set(0) {}

//set应用 set构造函数可以接受数组或者其他可遍历的数据结构
//数组去重 
let set=new Set([1,2,3,4,1,2,3,4]);
console.log(set);  //Set(4) { 1, 2, 3, 4 }
//数组去重 
let arr=[1,2,3,5,3,2];
let result=new Set(arr);
console.log(result);  //Set(4) { 1, 2, 3, 5 }
//将字符串转换为数组
let [...arr1]='hello'; //[ 'h', 'e', 'l', 'l', 'o' ]
//将set集合转换为数组
let [...arr2]=result;
console.log(arr2);  //[ 1, 2, 3, 5 ]

console.log([...new Set(arr)]) //[ 1, 2, 3, 5 ]

let s = new Set();
s.add([1]);
s.add([1]);
console.log(s); //Set(2) { [ 1 ], [ 1 ] }
//返回set成员个数
console.log(s.size); //2

3.Map集合

3.1概念

Map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。键不可以重复,值可以重复,键重复则后者覆盖前者,Map集合没有继承Collection接口。

let obj={
    name:"zhangsan",
    age:12
}
//遍历键值对组成的数组
let arr=Object.entries(obj);
console.log(arr); //[ [ 'name', 'zhangsan' ], [ 'age', 12 ] ]
//将数组作为参数放到Map中
let map=new Map(arr)
console.log(map); //Map(2) { 'name' => 'zhangsan', 'age' => 12 }

// 添加元素
map.set('1','1');
console.log(map); //Map(3) { 'name' => 'zhangsan', 'age' => 12, '1' => '1' }
// 删除元素
map.delete('name');
console.log(map); //Map(2) { 'age' => 12, '1' => '1' }
// 获取元素
console.log(map.get('age')); //12

let obj = {
    name: 'zhangsan',
    age: 12
};
let arr = Object.entries(obj);
let map = new Map(arr);
let keys = map.keys();
let values = map.values();
let entries = map.entries();
console.log(keys); //[Map Iterator] { 'name', 'age' }
console.log(values); //[Map Iterator] { 'zhangsan', 12 }
console.log(entries); //[Map Entries] { [ 'name', 'zhangsan' ], [ 'age', 12 ] }
// 遍历
map.forEach((value,key)=>{
    console.log(value,key); //zhangsan name  12 age
})

let obj = {
    name: 'zhangsan',
    age: 12
};
let arr = Object.entries(obj);
let map = new Map(arr);
for (let k of map) {
    console.log(k); //[ 'name', 'zhangsan' ] [ 'age', 12 ]
}
console.log(map.__proto__);//Object [Map] {}

3.2map和object区别?

  1. map的键可以是任意数据类型,object的键只能是字符串或者symbol;
  2. map是一个可迭代的数据结构长度,object不可以直接迭代;
  3. map可以通过size属性获取数据结构长度,object不可以直接获取;
  4. map循环遍历按照循序进行输出,object属性无序数据结构。
Map Object
意外的键Map 默认情况不包含任何键。只包含显式插入的键。一个 Object 有一个原型, 原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
键的类型一个 Map的键可以是任意值,包括函数、对象或任意基本类型。一个Object 的键必须是一个 String 或是Symbol。
键的顺序Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。一个 Object 的键是无序的。注意:自ECMAScript 2015规范以来,对象确实保留了字符串和Symbol键的创建顺序; 因此,在只有字符串键的对象上进行迭代将按插入顺序产生键。
SizeMap 的键值对个数可以轻易地通过size 属性获取Object 的键值对个数只能手动计算
迭代Map 是 iterable 的,所以可以直接被迭代。迭代一个Object需要以某种方式获取它的键然后才能迭代。
性能在频繁增删键值对的场景下表现更好。在频繁添加和删除键值对的场景下未作出优化。

4.数据扩展

4.1 Number.isFinite(), Number.isNaN()

与isFinite、isNaN不同,这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false

Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isNaN(NaN) // true
Number.isNaN(15) // false

4.2 Number.parseInt(), Number.parseFloat()

ES6 将全局方法parseInt()parseFloat(),移植到Number对象上面,行为完全保持不变。

Number.parseInt('12.34') // 12
Number.parseFloat('123.45#') // 123.45

4.3 Number.isInteger()

Number.isInteger()用来判断一个数值是否为整数。

Number.isInteger(25) // true
Number.isInteger(25.1) // false

5. async异步函数

5.1概念

async函数是使用async关键字声明的函数。 async函数是AsyncFunction构造函数的实例, 并且其中允许使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用promise。

await关键字只在async函数内有效。如果你在async函数体之外使用它,就会抛出语法错误 SyntaxError 。async/await的目的为了简化使用基于promise的API时所需的语法。async/await的行为就好像搭配使用了生成器和promise。async函数一定会返回一个promise对象。如果一个async函数的返回值看起来不是promise,那么它将会被隐式地包装在一个promise中。

简单来说 是一个函数,是一个异步编程解决方案,内部封装了generator函数,是一个语法糖,内部自带执行器,与await配合使用;异步编程,同步处理;

  async function loadAll() {
            // 发送一个请求 get
            try {
                let res = await axios.get('http://121.199.0.35:8898/index/article/findCategoryArticles');
                console.log(res);
            } catch (error) {
                // console.log(error);
                // throw 抛出错误
                throw new Error;
            } finally {
                console.log('最终请求');
            }
            // try catch finally
            // 捕获异常

        }
        loadAll();

forEach、for in、for of三者区别

forEach更多用来遍历数组

for in 一般常用来遍历对象或json

for of数组对象都可以遍历,遍历对象需要通过和Object.keys()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用迭代器遍历std::map。下面是一个示例代码: ``` #include <iostream> #include <map> int main() { std::map<int, int> myMap; myMap[0] = 1; myMap[1] = 2; myMap[2] = 3; std::map<int, int>::iterator it; for (it = myMap.begin(); it != myMap.end(); ++it) { std::cout << it->first << " => " << it->second << '\n'; } return 0; } ``` 这段代码将使用迭代器遍历map,并打印出每一对键值。 ### 回答2: 在C++中,map是一种内置容器,用于存储一些键值对。当我们需要遍历map容器时,可以使用迭代器iterator,它是一种指向容器元素的对象,可以通过它访问map中的每个元素。 使用迭代器iterator遍历map时,需要先定义一个迭代器,然后通过循环语句来遍历map中的每个元素。以下是使用迭代器iterator遍历map的示例程序: ``` #include <iostream> #include <map> using namespace std; int main() { // 定义一个map容器 map<int,string> myMap; // 往map容器中添加元素 myMap.insert(pair<int,string>(1,"apple")); myMap.insert(pair<int,string>(2,"banana")); myMap.insert(pair<int,string>(3,"pear")); // 定义一个迭代器iterator map<int,string>::iterator it; // 遍历map容器中的每个元素 for(it=myMap.begin(); it!=myMap.end(); ++it) { cout<<"key="<<it->first<<", value="<<it->second<<endl; } return 0; } ``` 上述程序中,首先定义了一个map容器myMap,并添加了三个元素。然后定义一个迭代器iterator it,通过循环语句遍历了map容器中的每个元素,输出了它们的键值对。 需要注意的是,在遍历map容器时,应该从begin()开始循环到end(),并使用箭头运算符->来访问每个元素的键与值。 在使用map容器时,使用迭代器iterator遍历map是一种非常方便和高效的方法,它可以让我们方便地访问map中的每个元素。 ### 回答3: 迭代器(iterator)是C++语言中非常重要的一个概念,它是STL(标准模板库)中许多STL容器的一种通用的访问机制,其中就包括map(映射容器)。在STL之前,为了对一个容器中的对象进行遍历,需要使用指针或数组来进行遍历,效率较低并且操作不够便捷。而迭代器方法则被广泛采用,具有高效、类型安全、灵活等优点。 在C++中,要遍历一个map,可以通过使用迭代器来完成。迭代器是C++中最基本的容器适配器之一,它是一个指针对象,可以通过它来访问容器中的元素。对于map容器来说,它的元素是由键(key)和值(value)组成,我们可以通过迭代器来获取或修改map中元素的键值对。 遍历一个map容器的迭代器使用方法如下: ``` //假设有一个map容器m map<int, string> m; //使用迭代器遍历map容器 for(map<int, string>::iterator it = m.begin(); it != m.end(); it++){ cout << it->first << " : " << it->second << endl; } ``` 通过上述代码可以看出,迭代器在遍历map容器时有以下三个关键步骤: 1. 使用m.begin()方法获取map的起始迭代器,即指向map第一个元素的迭代器; 2. 使用m.end()方法获取map的结束迭代器,即指向map最后一个元素的迭代器的下一个位置; 3. 使用for循环对起始迭代器进行迭代,并对迭代器的指向元素进行操作。 其中,对于map容器的迭代器使用,还有两个方法需要介绍: 1. map容器的迭代器是支持“++”操作符的,即用“++”运算符来将迭代器移动到下一个位置(指向下一个键值对); 2. 对于map容器的迭代器来说,it->first表示键,it->second表示值。即通过迭代器访问map中的键值对时,可用it->first来获取其键,用it->second来获取其值。 总之,使用迭代器遍历map容器,可以极大地方便我们对map容器中的元素进行操作,提高我们的编程效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值