当前位置: 首页 > news >正文

JavaScript系列(8)-- Array高级操作

JavaScript Array高级操作 📚

在前七篇文章中,我们探讨了JavaScript的语言特性、ECMAScript标准、引擎工作原理、数值类型、字符串处理、Symbol类型和Object高级特性。今天,让我们深入了解JavaScript中的Array高级操作。数组是最常用的数据结构之一,掌握其高级操作可以让我们更优雅地处理数据。

数组基础回顾 🌟

💡 小知识:JavaScript中的数组实际上是一种特殊的对象,它的索引是字符串类型的数字,并且有一个特殊的length属性。这种实现方式使得JavaScript数组比传统的数组更灵活,但在某些情况下性能可能不如传统数组。

数组的创建和初始化 📊

// 1. 数组创建的多种方式
function arrayCreation() {// 字面量方式const arr1 = [1, 2, 3, 4, 5];// 构造函数方式const arr2 = new Array(3);  // 创建长度为3的空数组const arr3 = new Array(1, 2, 3);  // 创建包含1,2,3的数组// Array.from方式const arr4 = Array.from('hello');  // ['h', 'e', 'l', 'l', 'o']const arr5 = Array.from({ length: 5 }, (_, i) => i + 1);  // [1, 2, 3, 4, 5]// Array.of方式const arr6 = Array.of(3);  // [3]const arr7 = Array.of(1, 2, 3);  // [1, 2, 3]// 扩展运算符const existing = [1, 2, 3];const arr8 = [...existing, 4, 5];  // [1, 2, 3, 4, 5]
}// 2. 类型化数组
function typedArrays() {// 创建类型化数组const int8Array = new Int8Array(4);const uint8Array = new Uint8Array(4);const int16Array = new Int16Array(4);const float32Array = new Float32Array(4);const float64Array = new Float64Array(4);// 从普通数组创建const numbers = [1, 2, 3, 4];const typed = new Int32Array(numbers);// 类型化数组的操作typed[0] = 10;console.log(typed.byteLength);  // 字节长度console.log(typed.buffer);      // 底层ArrayBuffer
}// 3. 数组缓冲区和视图
function arrayBuffers() {// 创建ArrayBufferconst buffer = new ArrayBuffer(16);// 创建不同的视图const int32View = new Int32Array(buffer);const float64View = new Float64Array(buffer);const uint8View = new Uint8Array(buffer);// 通过视图操作数据int32View[0] = 42;console.log(uint8View[0]);  // 查看字节级表示
}

数组操作方法 🔧

JavaScript提供了丰富的数组操作方法:

// 1. 基本操作
function basicOperations() {const arr = [1, 2, 3, 4, 5];// 添加和删除元素arr.push(6);           // 末尾添加arr.unshift(0);        // 开头添加arr.pop();             // 末尾删除arr.shift();           // 开头删除// 切片和拼接const slice = arr.slice(1, 3);    // 复制部分数组const spliced = arr.splice(1, 2, 'a', 'b');  // 替换元素// 合并数组const arr1 = [1, 2];const arr2 = [3, 4];const combined = arr1.concat(arr2);// 或使用扩展运算符const combined2 = [...arr1, ...arr2];
}// 2. 高阶函数操作
function higherOrderOperations() {const numbers = [1, 2, 3, 4, 5];// map: 转换每个元素const doubled = numbers.map(x => x * 2);// filter: 筛选元素const evens = numbers.filter(x => x % 2 === 0);// reduce: 累积计算const sum = numbers.reduce((acc, cur) => acc + cur, 0);// find/findIndex: 查找元素const found = numbers.find(x => x > 3);const foundIndex = numbers.findIndex(x => x > 3);// every/some: 条件检查const allPositive = numbers.every(x => x > 0);const hasEven = numbers.some(x => x % 2 === 0);// flatMap: 映射并展平结果const pairs = numbers.flatMap(x => [x, x * 2]);
}// 3. 排序和搜索
function sortingAndSearching() {const items = [{ name: '苹果', price: 5 },{ name: '香蕉', price: 3 },{ name: '橙子', price: 4 }];// 基本排序items.sort((a, b) => a.price - b.price);// 自定义排序items.sort((a, b) => {if (a.name < b.name) return -1;if (a.name > b.name) return 1;return 0;});// 二分查找const numbers = [1, 3, 5, 7, 9, 11];const index = numbers.indexOf(7);// 自定义二分查找function binarySearch(arr, target) {let left = 0;let right = arr.length - 1;while (left <= right) {const mid = Math.floor((left + right) / 2);if (arr[mid] === target) return mid;if (arr[mid] < target) left = mid + 1;else right = mid - 1;}return -1;}
}

数组的高级技巧 🎯

让我们看看一些高级的数组操作技巧:

// 1. 数组去重
function arrayDeduplication() {// 使用Setfunction uniqueArray1(arr) {return [...new Set(arr)];}// 使用filterfunction uniqueArray2(arr) {return arr.filter((item, index) => arr.indexOf(item) === index);}// 使用reducefunction uniqueArray3(arr) {return arr.reduce((unique, item) => unique.includes(item) ? unique : [...unique, item], []);}// 对象数组去重function uniqueObjectArray(arr, key) {const seen = new Set();return arr.filter(item => {const value = item[key];if (seen.has(value)) return false;seen.add(value);return true;});}
}// 2. 数组分组和分块
function arrayGrouping() {// 按条件分组function groupBy(arr, key) {return arr.reduce((groups, item) => {const value = typeof key === 'function' ? key(item) : item[key];(groups[value] = groups[value] || []).push(item);return groups;}, {});}// 分块function chunk(arr, size) {return Array.from({ length: Math.ceil(arr.length / size) },(_, i) => arr.slice(i * size, (i + 1) * size));}// 按数量分割function partition(arr, n) {const size = Math.ceil(arr.length / n);return chunk(arr, size);}
}// 3. 数组交集、并集和差集
function arraySetOperations() {// 交集function intersection(arr1, arr2) {return arr1.filter(item => arr2.includes(item));}// 并集function union(arr1, arr2) {return [...new Set([...arr1, ...arr2])];}// 差集function difference(arr1, arr2) {return arr1.filter(item => !arr2.includes(item));}// 对称差集function symmetricDifference(arr1, arr2) {return arr1.filter(item => !arr2.includes(item)).concat(arr2.filter(item => !arr1.includes(item)));}
}

数组性能优化 ⚡

处理大型数组时的性能优化技巧:

// 1. 预分配内存
function memoryPreallocation() {// 预分配数组大小const n = 1000000;const arr = new Array(n);// 不好的做法const dynamicArr = [];for (let i = 0; i < n; i++) {dynamicArr.push(i);  // 可能导致多次重新分配内存}// 好的做法const preallocatedArr = new Array(n);for (let i = 0; i < n; i++) {preallocatedArr[i] = i;}
}// 2. 批量操作优化
function batchOperations() {// 使用TypedArray进行数值计算function computeSum(arr) {const typed = new Float64Array(arr);let sum = 0;for (let i = 0; i < typed.length; i++) {sum += typed[i];}return sum;}// 批量插入优化function batchInsert(arr, items) {const temp = [...arr];temp.push(...items);return temp;}
}// 3. 迭代器优化
function iteratorOptimization() {// 使用for...of代替forEachfunction sumArray(arr) {let sum = 0;for (const num of arr) {sum += num;}return sum;}// 使用迭代器处理大数据function* chunks(arr, size) {for (let i = 0; i < arr.length; i += size) {yield arr.slice(i, i + size);}}
}

实际应用场景 💼

让我们看看数组在实际开发中的一些应用:

// 1. 数据处理
class DataProcessor {// 数据转换static transform(data, transformers) {return data.map(item => transformers.reduce((acc, transformer) => transformer(acc), item));}// 数据过滤和排序static filterAndSort(data, filters, sorter) {return data.filter(item => filters.every(filter => filter(item))).sort(sorter);}// 数据聚合static aggregate(data, groupBy, aggregator) {const groups = this.groupBy(data, groupBy);return Object.entries(groups).map(([key, group]) => ({key,value: aggregator(group)}));}
}// 2. 虚拟列表
class VirtualList {constructor(data, pageSize) {this.data = data;this.pageSize = pageSize;this.currentPage = 0;}getCurrentPage() {const start = this.currentPage * this.pageSize;return this.data.slice(start, start + this.pageSize);}next() {if (this.hasNext()) {this.currentPage++;return this.getCurrentPage();}return [];}previous() {if (this.hasPrevious()) {this.currentPage--;return this.getCurrentPage();}return [];}hasNext() {return (this.currentPage + 1) * this.pageSize < this.data.length;}hasPrevious() {return this.currentPage > 0;}
}// 3. 数据缓存
class ArrayCache {constructor(maxSize = 1000) {this.maxSize = maxSize;this.cache = new Map();}set(key, array) {if (this.cache.size >= this.maxSize) {const firstKey = this.cache.keys().next().value;this.cache.delete(firstKey);}this.cache.set(key, array);}get(key) {return this.cache.get(key);}has(key) {return this.cache.has(key);}clear() {this.cache.clear();}
}

最佳实践建议 💡

  1. 数组操作最佳实践
// 1. 避免稀疏数组
function avoidSparseArrays() {// 不好的做法const sparse = [1, , 3];// 好的做法const dense = [1, null, 3];// 转换稀疏数组为密集数组const densified = sparse.filter(() => true);
}// 2. 使用合适的数组方法
function chooseRightMethods() {const arr = [1, 2, 3, 4, 5];// 查找元素// 不好的做法const found1 = arr.filter(x => x === 3)[0];// 好的做法const found2 = arr.find(x => x === 3);// 转换数组// 不好的做法const transformed1 = arr.reduce((acc, x) => [...acc, x * 2], []);// 好的做法const transformed2 = arr.map(x => x * 2);
}// 3. 性能考虑
function performanceConsiderations() {// 避免频繁修改数组长度const arr = [];const n = 1000;// 不好的做法for (let i = 0; i < n; i++) {arr.push(i);}// 好的做法const arr2 = Array.from({ length: n }, (_, i) => i);
}
  1. 错误处理和验证
// 1. 数组验证
function validateArray(arr) {if (!Array.isArray(arr)) {throw new TypeError('参数必须是数组');}if (arr.length === 0) {throw new Error('数组不能为空');}return true;
}// 2. 安全的数组操作
function safeArrayOperations() {function safeGet(arr, index, defaultValue = null) {if (!Array.isArray(arr)) return defaultValue;if (index < 0 || index >= arr.length) return defaultValue;return arr[index];}function safeSplice(arr, start, deleteCount, ...items) {const copy = [...arr];copy.splice(start, deleteCount, ...items);return copy;}
}// 3. 类型检查
function arrayTypeChecking() {function isNumberArray(arr) {return Array.isArray(arr) && arr.every(x => typeof x === 'number');}function isObjectArray(arr) {return Array.isArray(arr) && arr.every(x => x && typeof x === 'object');}
}

结语 📝

JavaScript的数组操作非常强大和灵活,掌握这些高级操作可以帮助我们更好地处理数据。我们学习了:

  1. 数组的创建和初始化方法
  2. 常用的数组操作方法
  3. 高级数组操作技巧
  4. 性能优化和最佳实践
  5. 实际应用场景

💡 学习建议:在处理数组时,要根据具体场景选择合适的方法,注意性能影响,特别是在处理大型数组时。同时,要注意数组操作的副作用,优先使用不改变原数组的方法。


如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

http://www.lryc.cn/news/516254.html

相关文章:

  • Harmony开发【笔记1】报错解决(字段名写错了。。)
  • MAC环境安装(卸载)软件
  • 【Vim Masterclass 笔记05】第 4 章:Vim 的帮助系统与同步练习(L14+L15+L16)
  • Multisim更新:振幅调制器+解调器(含仿真程序+文档+原理图+PCB)
  • CentOS — 群组管理
  • 【pytorch】注意力机制-1
  • html 元素中的data-v-xxxxxx 是什么?为什么有的元素有?有的没有?
  • 第27周:文献阅读及机器学习
  • 回归预测 | MATLAB实ELM-Adaboost多输入单输出回归预测
  • Swift Protocols(协议)、Extensions(扩展)、Error Handling(错误处理)、Generics(泛型)
  • .NET中的强名称和签名机制
  • 使用 NestJS 构建高效且模块化的 Node.js 应用程序,从安装到第一个 API 端点:一步一步指南
  • 2025年大模型技术发展趋势展望:高速旋转的飞轮
  • java中类的加载过程及各个阶段与运行时数据区中堆和方法区存储内容
  • 渗透测试--Web基础漏洞利用技巧
  • SpringBoot下载文件的几种方式
  • 教程:从pycharm基于anaconda构建机器学习环境并运行第一个 Python 文件
  • 我用Ai学Android Jetpack Compose之Button
  • 修改secure-file-priv参数-mysql5.7.26限制不允许导入或导出的解决方法
  • C# 设计模式(结构型模式):适配器模式
  • Spring Cloud微服务多模块架构:父子工程搭建实践
  • SkinnedMeshRenderer相关知识
  • 前端学习DAY30(水平)
  • Spring boot 项目 Spring 注入 代理 并支持 代理对象使用 @Autowired 去调用其他服务
  • Colyseus 与 HTTP API 的集成
  • 基于服务器部署的综合视频安防系统的智慧快消开源了。
  • SpringBoot原理分析-1
  • HCIA-Access V2.5_7_5_XG(S)- GPON网络演进为XG(S)-PON网络
  • GPU算力平台的应用之任意门:任意穿搭匹配模型的应用教程
  • 如何利用人工智能算法优化知识分类和标签?