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

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() {
    // 创建ArrayBuffer
    const 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() {
    // 使用Set
    function uniqueArray1(arr) {
        return [...new Set(arr)];
    }
    
    // 使用filter
    function uniqueArray2(arr) {
        return arr.filter((item, index) => arr.indexOf(item) === index);
    }
    
    // 使用reduce
    function 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代替forEach
    function 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.kler.cn/a/469142.html

相关文章:

  • 苹果系统MacOS下ObjectC建立的App程序访问opencv加载图片程序
  • 计算机网络与服务器
  • Linux(Centos 7.6)命令详解:mkdir
  • STM32 I2C通信外设
  • C语言的正则表达式
  • 桌面运维岗面试三十问
  • javaEE-网络编程-3 UDP
  • LabVIEW 实现自动对焦的开发
  • 编译与汇编
  • kubelet状态错误报错
  • linux 逻辑卷挂盘
  • F.interpolate函数
  • [Linux]redis5.0.x升级至7.x完整操作流程
  • 使用MySQL APT源在Linux上安装MySQL
  • spring mvc源码学习笔记之五
  • 【华为OD-E卷 - 九宫格按键输入 100分(python、java、c++、js、c)】
  • Linux系统常用命令详解
  • 怎么找回电脑所有连接过的WiFi密码
  • 【论文阅读笔记】LTX-Video: Realtime Video Latent Diffusion
  • 如何让编码更加高效专注?——程序员编程选明基 RD280U显示器
  • Django Swagger文档库drf-spectacular
  • 【Rust 知识点杂记】
  • 微信小程序提示 miniprogram-recycle-view 引入失败
  • leetcode hot 100 最长递增子序列
  • 智能体语言 Shire 1.2 发布:自定义多文件编辑、Sketch 视图、流式 diff、智能上下文感知...
  • AI生成PPT,效率与创意的双重升级