给javascript 的 array 添加remove 和 removeall 属性

本文介绍了一种在JavaScript中扩展数组原型的方法,通过定义remove和removeAll函数来方便地从数组中移除特定元素或清空整个数组。这些实用的功能可以提高开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

function RemoveArray(array, attachId) {
    for (var i = 0,n = 0; i < array.length; i++) {
        if (array[i] != attachId) {
            array[n++] = array[i]
        }
    }
    array.length -= 1;
}


Array.prototype.remove = function (obj) {
    return RemoveArray(this, obj);
};


Array.prototype.removeAll = function() {
    this.length = 0;
}

<think>好的,用户之前已经问过如何在H5中实现类似链表的数据存储,我给出了详细的内存持久化方案。现在用户的新问题是具体关于链表的添加、读取删除操作的实现。我需要确保回答结构清晰,步骤详细,并且结合之前的代码示例进行扩展。 首先,用户可能需要具体的代码示例解释,所以得分别针对内存链表持久化链表两种情况来讲解这三个操作。在内存链表中,添加删除已经部分展示过,但可能需要补充读取的方法。而持久化链表方面,之前的代码主要展示了初始化数据库添加节点,现在需要补充读取删除的实现,尤其是如何处理IndexedDB的异步操作。 另外,用户可能关心的是操作的时间复杂度,所以在每个操作后应该注明复杂度,比如添加尾部是O(1),删除是O(n)等。同时,应用场景注意事项也需要再次强调,帮助用户理解实际使用中的问题,比如持久化时的原子操作错误处理。 需要注意用户可能对IndexedDB的操作不太熟悉,所以代码示例需要尽可能详细,并解释每一步的作用。例如,在删除节点时,要更新前驱节点的nextId,并处理可能的异常情况,如节点不存在或事务失败。 此外,用户可能希望了解如何优化这些操作,比如使用缓存或批量处理,这在之前的回答中提到过,可能需要再次提及,但当前问题主要关注基本操作,所以可以放在优化建议部分,简要说明。 最后,要确保回答符合系统级指令,比如使用正确的LaTeX格式,独立公式用$$,行内公式用$。同时,结构要清晰,分步骤讲解,代码块正确标注语言类型,保持中文回答。需要检查是否有遗漏的操作步骤,或者是否有可以进一步简化的地方,让用户更容易理解实现。</think>以下是H5环境下使用JavaScript实现链表数据结构的完整操作指南,包含数据添加、读取删除的核心实现及详细说明: --- ### 一、内存链表基础操作 #### 1. 数据添加 ```javascript class LinkedList { // 头部插入($$O(1)$$) prepend(data) { const node = new ListNode(data) node.next = this.head this.head = node if (!this.tail) this.tail = node this.size++ } // 尾部追加($$O(1)$$) append(data) { const node = new ListNode(data) if (!this.head) { this.head = node } else { this.tail.next = node } this.tail = node this.size++ } } // 使用示例 const list = new LinkedList() list.append(10) // 尾部插入 list.prepend(5) // 头部插入 ``` #### 2. 数据读取 ```javascript class LinkedList { // 按索引访问($$O(n)$$) getAt(index) { if (index < 0 || index >= this.size) return null let current = this.head let count = 0 while (count < index) { current = current.next count++ } return current.data } // 遍历输出($$O(n)$$) printAll() { let current = this.head while (current) { console.log(current.data) current = current.next } } } // 使用示例 console.log(list.getAt(1)) // 输出第二个节点数据 list.printAll() // 遍历全部节点 ``` #### 3. 数据删除 ```javascript class LinkedList { // 按值删除($$O(n)$$) removeByValue(value) { let current = this.head let prev = null while (current) { if (current.data === value) { if (prev) { prev.next = current.next if (!current.next) this.tail = prev } else { this.head = current.next } this.size-- return true } prev = current current = current.next } return false } // 按索引删除($$O(n)$$) removeAt(index) { if (index === 0) { this.head = this.head.next if (!this.head) this.tail = null this.size-- return true } let current = this.head let prev = null let count = 0 while (current && count < index) { prev = current current = current.next count++ } if (current) { prev.next = current.next if (!current.next) this.tail = prev this.size-- return true } return false } } ``` --- ### 二、持久化链表操作(结合IndexedDB) #### 1. 数据添加流程 ```javascript class PersistentLinkedList { async append(data) { const transaction = this.db.transaction(['nodes'], 'readwrite') const store = transaction.objectStore('nodes') // 获取当前尾节点 const tail = await new Promise(resolve => { const request = store.index('nextId').openCursor(null, 'prev') request.onsuccess = e => resolve(e.target.result?.value) }) // 插入新节点 const newNode = { data, nextId: null } const addRequest = store.add(newNode) return new Promise((resolve, reject) => { addRequest.onsuccess = async (e) => { const newId = e.target.result if (tail) { // 原子更新前驱节点 tail.nextId = newId await this.updateNode(tail) } resolve(newId) } addRequest.onerror = reject }) } } ``` #### 2. 数据读取实现 ```javascript class PersistentLinkedList { // 顺序遍历($$O(n)$$) async traverse() { const result = [] let currentId = await this.getHeadId() while (currentId !== null) { const node = await this.getNode(currentId) result.push(node.data) currentId = node.nextId } return result } // 获取头节点ID async getHeadId() { return new Promise(resolve => { const request = this.db.transaction('nodes').objectStore('nodes') .index('nextId').openKeyCursor(null, 'prev') request.onsuccess = e => resolve(e.target.result?.primaryKey || null) }) } // 获取单个节点 async getNode(id) { return new Promise((resolve, reject) => { const request = this.db.transaction('nodes').objectStore('nodes').get(id) request.onsuccess = e => resolve(e.target.result) request.onerror = reject }) } } ``` #### 3. 数据删除策略 ```javascript class PersistentLinkedList { async deleteNode(targetId) { const transaction = this.db.transaction(['nodes'], 'readwrite') const store = transaction.objectStore('nodes') // 查找前驱节点 const prevNode = await this.findPreviousNode(targetId) if (prevNode) { // 更新前驱节点的nextId prevNode.nextId = (await this.getNode(targetId)).nextId await this.updateNode(prevNode) } // 删除目标节点 await new Promise((resolve, reject) => { const request = store.delete(targetId) request.onsuccess = resolve request.onerror = reject }) } // 查找前驱节点($$O(n)$$) async findPreviousNode(targetId) { const transaction = this.db.transaction('nodes') const store = transaction.objectStore('nodes') return new Promise(resolve => { const request = store.index('nextId').openCursor(IDBKeyRange.only(targetId)) request.onsuccess = e => resolve(e.target.result?.value || null) }) } } ``` --- ### 三、性能优化建议 1. **批量操作优化**: ```javascript async bulkAppend(dataArray) { const transaction = this.db.transaction(['nodes'], 'readwrite') const store = transaction.objectStore('nodes') const operations = [] let lastId = await this.getTailId() dataArray.forEach(data => { const newNode = { data, nextId: null } operations.push(store.add(newNode).then(id => { if (lastId) { return store.get(lastId).then(node => { node.nextId = id return store.put(node) }) } return id })) lastId = id }) return Promise.all(operations) } ``` 2. **缓存加速方案**: ```javascript class CachedLinkedList { constructor() { this.cache = new Map() // ID -> Node this.headId = null } async getNode(id) { if (this.cache.has(id)) return this.cache.get(id) const node = await this.persistentStorage.getNode(id) this.cache.set(id, node) return node } } ``` --- ### 四、操作复杂度对比表 | 操作类型 | 内存链表 | 持久化链表 | 优化后持久化 | |----------------|----------|------------|--------------| | 头部插入 | $$O(1)$$ | $$O(1)$$ | $$O(1)$$ | | 尾部追加 | $$O(1)$$ | $$O(1)$$ | $$O(1)$$ | | 随机读取 | $$O(n)$$ | $$O(n)$$ | $$O(1)$$* | | 按值删除 | $$O(n)$$ | $$O(n)$$ | $$O(1)$$** | > *需配合缓存使用 > **需建立反向索引 --- ### 五、典型应用场景 1. **历史记录管理**:浏览器前进后退栈实现 2. **任务队列系统**:异步任务顺序执行 3. **版本控制系统**:文件修改历史追踪 4. **社交网络动态流**:时间线数据加载 --- ### 六、注意事项 1. **指针完整性验证**: ```javascript async validateLinks() { let currentId = this.headId while (currentId) { const node = await this.getNode(currentId) if (node.nextId && !(await this.nodeExists(node.nextId))) { throw new Error('发现断裂链接') } currentId = node.nextId } } ``` 2. **事务错误处理**: ```javascript async safeAppend(data) { try { return await this.append(data) } catch (error) { console.error('操作失败:', error) await this.rollbackTransaction() throw error } } ``` 3. **内存释放策略**: ```javascript class MemoryLinkedList { clear() { let current = this.head while (current) { const next = current.next current.next = null // 断开引用 current = next } this.head = null this.tail = null this.size = 0 } } ``` 通过合理选择数据结构实现方案,结合浏览器存储能力,可在H5应用中构建高效可靠的数据管理系统。建议根据实际场景选择内存链表(高频操作)或持久化链表(数据安全优先)方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值