0x000 概述
这里讲的数组是指数据结构中的数组,而不是专指js
中的数组,只是使用js
来探究数据结构中的数组,因为我觉得js
比较方便。
0x001 数组
- 数组是啥?看图:
-
数组有两个要素:
- 索引:图中的
0,1,2,3,4
- 数据:图中的
data1
-data5
可以通过索引找到某个数据,然后对这个数据操作,而这里的数据是泛指,因为数组是一种通用的数据结构,可以存储任意的数据,比如数字、对象、字符串,甚至数组也可以。
- 索引:图中的
-
数组的操作
- 搜索
- 添加/更新
- 删除
0x002 初始化
js
中数组的初始化很简单,方式也很多:
[] // []
[1,2,3,4,5,6,7] //[1,2,3,4,5,6,7]
new Array() //[]
new Array(10) // [ 10 empty items]
new Array(1,2,3,4,6) // [1,2,3,4,5,6]
Array.from([1,2,3,4,5],(a)=>a*2) // [2,4,6,8,10]
Array.from(new Set([1,2,3,3])) // [1,2,3]
这里我们选择最简单的来实现init
:
function init() {
return []
}
0x002 插入
js
中插入的方法也很多,每个方法也都有自己的特色,其实js
的数组就已经自带实现了很多的数据结构
let data=[]
data[0]=1 // [1]
data.push(2) // [1, 2]
data=data.concat(3) // [1, 2, 3]
data=data.concat([4],5) // [1, 2, 3, 4, 5]
我们依旧选择最简单索引方式,因为这比较符合数据结构中数组的使用,push
是更适合其他数据结构的操作。
function insert(arr, index, data) {
arr[index] = data
return arr
}
0x003 查找
js
数组查找的方法也很多
let data = [1, 2, 3, 4, 5, 6]
data.find(d => d === 1) // 1
data[data.findIndex(d => d === 2)] //2
data.filter(d => d === 3)[0] // 3
data.forEach(d => {
if (d === 4) {
result = d // 4
}
})
for (let i = 0; i < data.length; i++) {
if (data[i] === 5) {
result = data[i] // 5
break
}
}
for (var d of data) {
if (d === 6) {
result = d //6
break
}
}
我们依旧采用最简单的
function find(arr, data) {
return arr.find(d => d === data)
}
0x004 删除
js
的删除...也有很多方法
let data = [1, 2, 3, 4, 5, 6]
delete data[0] // [ <1 empty item>, 2, 3, 4, 5, 6 ]
data.pop() // [ <1 empty item>, 2, 3, 4, 5]
data.splice(0, 1) // [2, 3, 4, 5]
我们依旧采用最简单的
function delete_(arr, index) {
arr.splice(index,1)
return arr
}
0x005 使用
function main() {
let arr = init()
arr = insert(arr, 0, 1) // [1]
arr = insert(arr, 1, 2) // [1, 2]
arr = insert(arr, 2, 3) // [1, 2, 3]
arr = insert(arr, 3, 4) // [1, 2, 3, 4]
arr = insert(arr, 4, 5) // [1, 2, 3, 4, 5]
arr = insert(arr, 5, 6) // [1, 2, 3, 4, 5, 6]
find(arr, 1) // 1
find(arr, 2) // 2
find(arr, 3) // 3
find(arr, 4) // 4
find(arr, 5) // 5
delete_(arr, 0)
delete_(arr, 1)
delete_(arr, 2)
delete_(arr, 3)
delete_(arr, 4)
delete_(arr, 5)
}
0x006 注意
当然,我们平常并不会这么使用js
,这只是为了演示数组而已:
let data=[1,2,3]
data.push(4)
data.push(5)
data.push(6)
data.filter(d=>d===1)
data.splice(0,1)
0x007 栗子:使用数组完成todoList
- 效果
-
todoService
: 该文件用来提供todo
的增删改查服务let todoService = [] /** * 获取所有的 todo
*/
function getAll() {
return todoService
}
/**
* 添加一个 todo 到 todo 列表中
* @param todo
*/
function add(todo) {
todo.id = todoService.length
todoService.push(todo)
}
/**
* 根据 todo 的 id 删除一个 todo
* @param id
* @private
*/
function delete_(id) {
todoService.splice(findIndexById(id), 1)
}
/**
* 根据一个修改过的 todo 更新 todo
* @param todo
*/
function update(todo) {
todoService[findIndexById(todo.id)] = {...todo}
}
/**
* 根据内容筛选符合条件的 todo
* @param content
* @returns {*[]}
*/
function find(content) {
return todoService.filter(todo => todo.content === content)
}
/**
* 根据 id 获取这个 id 在 todoList 中的索引
* @param id
* @returns {number}
*/
function findIndexById(id) {
return todoService.findIndex(todo => todo.id === +id)
}
```
-
视图
<body class="container"> <div id="container"> <div class="mt-1"> <input class="form-control" type="text" id="inputContent"> <div class="mt-1"> <button class="btn btn-primary" id="btnAdd">添加</button> <button class="btn btn-info" id="btnSearch">搜索</button> <button class="btn btn-warning" id="btnUpdate">更新</button> </div> </div> <div class="mt-1"> <ul id="ulTodoList"> </ul> </div> </div> </body>
-
引入
todoService
<script src="./todoService.js.js"></script>
-
初始化变量
let $btnAdd = window.document.getElementById('btnAdd') let $btnSearch = window.document.getElementById('btnSearch') let $btnUpdate = window.document.getElementById('btnUpdate') let $ulTodoList = window.document.getElementById('ulTodoList') let $inputContent = window.document.getElementById('inputContent') let updateTodo
-
完成添加按钮的点击事件
当用户输入内容并点击添加的时候,会根据输入内容创建一个新的
todo
,并调用add
将新的todo
保存到todoList
中,接着调用render
将所有的todo
渲染到dom
中,最后清空输入框。$btnAdd.onclick = () => { let content = $inputContent.value add({content: content}) render([...getAll()]) $inputContent.value = '' }
-
完成搜索按钮点击事件
当用户输入内容并点击搜索按钮的时候,会根据输入的内容调用
find
,该函数返回了所有内容和输入内容相同的todo
,将这些todo
渲染到dom
中就获得了搜索之后的todo
,最后清空输入框。$btnSearch.onclick = () => { let content = $inputContent.value render(find(content)) $inputContent.value = '' }
-
完成
todoLsit
的渲染为了方便,该函数直接将
ul
的子元素全部清空,然后根据传入的todoList
重新渲染子元素,其中为每个一个todo
创建了一个删除
按钮和更新按钮
。删除
按钮点击的时候讲调用delete_
将这个todo
从todoList
中移除,更新
按钮点击的时候只会将当前的todo
保存到变量中,准备进行更新操作function render(todoList) { $ulTodoList.innerHTML = '' todoList.map((todo) => { let $li = document.createElement('li') $li.className = "mt-2" let $span = document.createElement('span') $span.innerText = todo.content let $btnDelete = document.createElement('button') $btnDelete.innerText = '删除' $btnDelete.className = 'btn btn-danger m-2' $btnDelete.onclick = () => { delete_(todo.id) render([...getAll()]) } let $btnUpdate = document.createElement('button') $btnUpdate.innerText = '更新' $btnUpdate.className = 'btn btn-warning m-2' $btnUpdate.onclick = () => { updateTodo = {...todo} $inputContent.value = todo.content } $li.appendChild($btnDelete) $li.appendChild($btnUpdate) $li.appendChild($span) $ulTodoList.appendChild($li) }) }
-
完成更新按钮点击事件
render
中更新
按钮点击的时候已经将要更新的todo
保存到updateTodo
中,当用户修改输入框内容并点击更新的时候,就会将旧的todo
和新的todo
合并成更新后的todo
,然后调用update
去更新这个todo
,接着再render
一次,最后清空输入框$btnUpdate.onclick = () => { update({...updateTodo, content: $inputContent.value}) render([...getAll()]) $inputContent.value = '' }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。