标签:rpo 信息 接下来 end element 为什么 处理 lis 模型
列表是一组有序的数据。每个列表中的数据项称为元素。在JavaScript中,列表中的元素可以是任意类型的数据。列表中可以保存多少元素没有确定,实际使用时元素的数量受到程序内存的限制。
现在我们来抽象一下列表的抽象数据类型定义
listSize(属性):列表中的元素个数
pos(属性):列表中的元素当前可访问的位置(位置指针)
length(方法):返回列表中元素的个数
clear(方法):清空列表中的所有元素
toString(方法):返回列表的字符串形式
getElement(方法):返回列表当前可访问位置对应的元素
insert(方法):在现有元素后面插入新元素
append(方法):在列表的末尾添加新元素
remove(方法):从列表中移除元素
front(方法):将列表的当前位置移动到第一个元素
end(方法):将列表的当前位置移动到最后一个元素
prev(方法):将列表的当前位置前移一位
next(方法):将列表的当前位置后移一位
hasNext(方法):判断列表在当前位置是否还有一下个元素
hasPrev(方法):判断列表在当前位置是否还有上一个元素
currPos(方法):返回列表的当前位置
moveTo(方法):将列表的当前位置移动到指定位置
上面抽象了列表的数据类型,包括要使用到的属性和方法,下面使用代码来实现一个列表类:
// 定义列表类 class List { constructor() { // 定义列表的元素个数 this.listSize = 0; // 列表的位置指针 this.pos = 0; // 列表的数据存储 this.dataSource = []; } // append: 列表增加元素 append(element) { this.dataSource[this.listSize++] = element; } // remove: 列表中删除元素 remove(element) { var findAt = this.find(element); if (findAt > -1) { this.dataSource.splice(findAt, 1); --this.listSize; return true; } return false; } // find:辅助方法,用于查找要操作的元素 find(element) { for (var i = 0; i < this.listSize; i++) { if (this.dataSource[i] === element) { return i; } } return -1; } // length:返回列表中的元素个数 length() { return this.listSize; } // toString: 返回列表的字符串形式 toString() { return this.dataSource.toString(); } // insert: 向列表中添加一个元素 insert(element, after) { var insertPos = this.find(after); if (insertPos > -1) { this.dataSource.splice(insertPos + 1, 0, element); ++this.listSize; return true; } return false; } // clear: 清空列表中的元素 clear() { this.dataSource.length = 0; this.listSize = this.pos = 0; } // front:指针归零(移动到列表的第一个元素的位置) front() { this.pos = 0; } // end: 指针移动到列表的最后一个元素的位置 end() { this.pos = this.listSize - 1; } // hasPrev: 判断指针是否可以向前移动 hasPrev() { return this.pos > 0 } // hasNext: 判断指针是否可以向后移动 hasNext() { return this.pos < this.listSize - 1 } // moveTo: 修改指针的位置 moveTo(position) { if (0 <= position && position <= this.listSize - 1) { this.pos = position; } } // prev: 指针向前移动一位 prev() { if (this.hasPrev()) { --this.pos; } } // next: 指针向后移动一位 next() { if (this.hasNext()) { ++this.pos; } } // getElement: 获取列表中指针所对应的元素 getElement() { return this.dataSource[this.pos]; } // currPos: 返回当前指针位置 currPos() { return this.pos; } }
其中next,prev,moveTo,front,end是我们设置的一些迭代器,使用迭代器有如下好处:
1. 访问列表元素的时候,我们不必关心底层的数据存储结构。
2.当对列表进行删除或增加操作的时候,存储列表元素的数组的索引值就更新了,此时只用更新列表,不需要更新迭代器。
3.可以用不同类型的数据存储方式来实现List类,迭代器为访问列表中的元素提供了一种统一的方式。
这样子我们就是实现了上面抽象的列表数据结构,接下来我们用它在做些什么。
创建一个Person 类,该类用于保存人的姓名和性别信息。创建一个至少包含10个Person对象的列表。编写一个函数显示列表中所有拥有相同性别的人。
分析如下,我们之前创建的列表类里面只适合操作基本数据类型,现在列表中的元素很明显是引用类型,所以我们想到的编写一个新的列表类,它拥有List类的所有方法,同时对有些方法实现覆盖,还要增加一些新的方法,以达到自己的需求。(之前定义的List类只是一个基本的模型而已,方便在实际应用中提供基础方法,自己实现相关的扩展)
代码如下:
// 定义列表类 class List { constructor() { // 定义列表的元素个数 this.listSize = 0; // 列表的位置指针 this.pos = 0; // 列表的数据存储 this.dataSource = []; } // append: 列表增加元素 append(element) { this.dataSource[this.listSize++] = element; } // remove: 列表中删除元素 remove(element) { var findAt = this.find(element); if (findAt > -1) { this.dataSource.splice(findAt, 1); --this.listSize; return true; } return false; } // find:辅助方法,用于查找要操作的元素 find(element) { for (var i = 0; i < this.listSize; i++) { if (this.dataSource[i] === element) { return i; } } return -1; } // length:返回列表中的元素个数 length() { return this.listSize; } // toString: 返回列表的字符串形式 toString() { return this.dataSource.toString(); } // insert: 向列表中添加一个元素 insert(element, after) { var insertPos = this.find(after); if (insertPos > -1) { this.dataSource.splice(insertPos + 1, 0, element); ++this.listSize; return true; } return false; } // clear: 清空列表中的元素 clear() { this.dataSource.length = 0; this.listSize = this.pos = 0; } // front:指针归零(移动到列表的第一个元素的位置) front() { this.pos = 0; } // end: 指针移动到列表的最后一个元素的位置 end() { this.pos = this.listSize - 1; } // hasPrev: 判断指针是否可以向前移动 hasPrev() { return this.pos > 0 } // hasNext: 判断指针是否可以向后移动 hasNext() { return this.pos < this.listSize - 1 } // moveTo: 修改指针的位置 moveTo(position) { if (0 <= position && position <= this.listSize - 1) { this.pos = position; } } // prev: 指针向前移动一位 prev() { if (this.hasPrev()) { --this.pos; } } // next: 指针向后移动一位 next() { if (this.hasNext()) { ++this.pos; } } // getElement: 获取列表中指针所对应的元素 getElement() { return this.dataSource[this.pos]; } // currPos: 返回当前指针位置 currPos() { return this.pos; } } // 创建Person类 class Person { constructor(name, sex) { this.name = name; this.sex = sex; } } class PersonList extends List { // 重写getElement方法 getElement() { return this.dataSource[this.pos].name; } // 返回指定性别人员集合 displayNames(sex){ return this.dataSource.filter(person=>person.sex === sex); } }; // 列表装载 const personList = new PersonList(); for (let i = 0; i < 10; i++) { personList.append(new Person(‘a‘ + i, Math.random() > 0.5 ? ‘男‘ : ‘女‘)); } console.log(personList.getElement()); // a0 personList.end(); console.log(personList.getElement());// a9 console.log(personList); console.log(‘personList列表中性别为男的人员组合为‘,personList.displayNames(‘男‘));
这样子我们就实现了需求,你可能会说需要这么麻烦,创建一个函数统计一下指定性别的人员就行了,为什么还要这些操作。其实在这里我们练习的是列表的使用,在这里只是举一个列子,其中滋味,自己体会。
有了之前的List类,我们处理一些相关的问题,通过简单的继承,就会变得相当简单。
我觉得学习新的知识之后,一定要用到实际开发中去,不然你学与不学有什么区别了,无非是浪费了一些时间来安慰自己罢了。
标签:rpo 信息 接下来 end element 为什么 处理 lis 模型
原文地址:https://www.cnblogs.com/jsydb/p/12491840.html