JavaScript 数组中删除偶数下标值的多种方法

  1. 使用 filter 方法(推荐)
javascript 复制代码
// 方法1: 使用filter保留奇数下标元素
const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

// 删除偶数下标(0, 2, 4, 6, 8...),保留奇数下标
const result1 = arr.filter((_, index) => index % 2 !== 0);
console.log(result1); // [1, 3, 5, 7, 9]

// 或删除奇数下标,保留偶数下标
const result2 = arr.filter((_, index) => index % 2 === 0);
console.log(result2); // [0, 2, 4, 6, 8]

2. 使用 for 循环(原地修改)

scss 复制代码
// 方法2: 从后向前遍历,原地删除
function removeEvenIndexes(arr) {
  // 从后向前遍历,避免索引错乱
  for (let i = arr.length - 1; i >= 0; i--) {
    if (i % 2 === 0) {  // 删除偶数下标
      arr.splice(i, 1);
    }
  }
  return arr;
}

const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(removeEvenIndexes(arr)); // [1, 3, 5, 7, 9]
console.log(arr); // 原数组也被修改
  1. 使用 reduce 方法
ini 复制代码
// 方法3: 使用reduce
const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

const result = arr.reduce((acc, cur, index) => {
  if (index % 2 !== 0) {  // 只保留奇数下标
    acc.push(cur);
  }
  return acc;
}, []);

console.log(result); // [1, 3, 5, 7, 9]
  1. 使用 for 循环创建新数组
ini 复制代码
// 方法4: 遍历奇数下标创建新数组
const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

function removeEvenIndexes(arr) {
  const result = [];
  for (let i = 0; i < arr.length; i++) {
    if (i % 2 !== 0) {  // 只取奇数下标
      result.push(arr[i]);
    }
  }
  return result;
}

console.log(removeEvenIndexes(arr)); // [1, 3, 5, 7, 9]
  1. while 循环 + splice
ini 复制代码
// 方法5: 使用while循环
const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

function removeEvenIndexes(arr) {
  let i = 0;
  while (i < arr.length) {
    if (i % 2 === 0) {  // 删除偶数下标
      arr.splice(i, 1);
    } else {
      i++;  // 只有不删除时才递增
    }
  }
  return arr;
}

console.log(removeEvenIndexes(arr)); // [1, 3, 5, 7, 9]
  1. 性能优化版本(大数据量)
javascript 复制代码
// 方法6: 高性能版本,避免splice
function removeEvenIndexesOptimized(arr) {
  const result = [];
  const length = arr.length;
  
  // 从第一个奇数下标开始,步长为2
  for (let i = 1; i < length; i += 2) {
    result.push(arr[i]);
  }
  
  return result;
}

// 测试大数据量
const largeArr = Array.from({ length: 1000000 }, (_, i) => i);
console.time('优化版');
const optimizedResult = removeEvenIndexesOptimized(largeArr);
console.timeEnd('优化版'); // 大约 5-10ms
console.log('结果长度:', optimizedResult.length); // 500000
  1. 原地修改的高效方法
// 复制代码
function removeEvenIndexesInPlace(arr) {
  let writeIndex = 0;
  
  for (let readIndex = 0; readIndex < arr.length; readIndex++) {
    if (readIndex % 2 !== 0) {  // 只保留奇数下标
      arr[writeIndex] = arr[readIndex];
      writeIndex++;
    }
  }
  
  // 截断数组
  arr.length = writeIndex;
  return arr;
}

const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(removeEvenIndexesInPlace(arr)); // [1, 3, 5, 7, 9]
console.log(arr); // 原数组被修改
  1. Vue 3 响应式数组处理
xml 复制代码
<template>
  <div>
    <h3>原始数组: {{ originalArray }}</h3>
    <h3>处理后: {{ processedArray }}</h3>
    <button @click="processArray">删除偶数下标</button>
    <button @click="resetArray">重置数组</button>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

// 原始响应式数组
const originalArray = ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

// 计算属性:删除偶数下标
const processedArray = computed(() => {
  return originalArray.value.filter((_, index) => index % 2 !== 0)
})

// 方法处理
const processArray = () => {
  // 方法1: 创建新数组(推荐,不修改原数组)
  originalArray.value = originalArray.value.filter((_, index) => index % 2 !== 0)
  
  // 方法2: 原地修改(会触发响应式更新)
  // let writeIndex = 0
  // for (let i = 0; i < originalArray.value.length; i++) {
  //   if (i % 2 !== 0) {
  //     originalArray.value[writeIndex] = originalArray.value[i]
  //     writeIndex++
  //   }
  // }
  // originalArray.value.length = writeIndex
}

const resetArray = () => {
  originalArray.value = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}
</script>
  1. 通用工具函数
javascript 复制代码
// 工具函数集合
const ArrayUtils = {
  /**
   * 删除偶数下标元素
   * @param {Array} arr - 输入数组
   * @param {boolean} inPlace - 是否原地修改
   * @returns {Array} 处理后的数组
   */
  removeEvenIndexes: function(arr, inPlace = false) {
    if (!Array.isArray(arr)) {
      throw new TypeError('输入必须是数组')
    }
    
    if (inPlace) {
      return this._removeEvenIndexesInPlace(arr)
    } else {
      return this._removeEvenIndexesNew(arr)
    }
  },
  
  /**
   * 创建新数组(不修改原数组)
   */
  _removeEvenIndexesNew: function(arr) {
    return arr.filter((_, index) => index % 2 !== 0)
  },
  
  /**
   * 原地修改
   */
  _removeEvenIndexesInPlace: function(arr) {
    let writeIndex = 0
    for (let i = 0; i < arr.length; i++) {
      if (i % 2 !== 0) {
        arr[writeIndex] = arr[i]
        writeIndex++
      }
    }
    arr.length = writeIndex
    return arr
  },
  
  /**
   * 删除奇数下标元素
   */
  removeOddIndexes: function(arr, inPlace = false) {
    if (inPlace) {
      let writeIndex = 0
      for (let i = 0; i < arr.length; i++) {
        if (i % 2 === 0) {
          arr[writeIndex] = arr[i]
          writeIndex++
        }
      }
      arr.length = writeIndex
      return arr
    } else {
      return arr.filter((_, index) => index % 2 === 0)
    }
  },
  
  /**
   * 删除指定下标的元素
   * @param {Array} arr - 输入数组
   * @param {Function} condition - 条件函数,返回true则删除
   */
  removeByIndexCondition: function(arr, condition, inPlace = false) {
    if (inPlace) {
      let writeIndex = 0
      for (let i = 0; i < arr.length; i++) {
        if (!condition(i)) {
          arr[writeIndex] = arr[i]
          writeIndex++
        }
      }
      arr.length = writeIndex
      return arr
    } else {
      return arr.filter((_, index) => !condition(index))
    }
  }
}

// 使用示例
const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

// 删除偶数下标
console.log(ArrayUtils.removeEvenIndexes(arr)) // [1, 3, 5, 7, 9]
console.log(arr) // 原数组不变 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

// 原地修改
console.log(ArrayUtils.removeEvenIndexes(arr, true)) // [1, 3, 5, 7, 9]
console.log(arr) // 原数组被修改 [1, 3, 5, 7, 9]

// 删除奇数下标
const arr2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(ArrayUtils.removeOddIndexes(arr2)) // [0, 2, 4, 6, 8]

// 自定义条件
const arr3 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(ArrayUtils.removeByIndexCondition(
  arr3, 
  index => index % 3 === 0
)) // 删除下标是3的倍数的元素
  1. ES6+ 高级写法
javascript 复制代码
// 使用生成器函数
function* filterByIndex(arr, condition) {
  for (let i = 0; i < arr.length; i++) {
    if (condition(i)) {
      yield arr[i]
    }
  }
}

const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const result = [...filterByIndex(arr, i => i % 2 !== 0)]
console.log(result) // [1, 3, 5, 7, 9]

// 使用箭头函数和三元运算符
const removeEvenIndexes = arr => arr.filter((_, i) => i % 2 ? arr[i] : null).filter(Boolean)

// 使用位运算(性能更好)
const removeEvenIndexesBit = arr => {
  const result = []
  for (let i = 1; i < arr.length; i += 2) {
    result.push(arr[i])
  }
  return result
}

// 使用 Array.from
const removeEvenIndexesFrom = arr => 
  Array.from(
    { length: Math.ceil(arr.length / 2) },
    (_, i) => arr[i * 2 + 1]
  ).filter(Boolean)
  1. TypeScript 版本
typescript 复制代码
// TypeScript 类型安全的版本
class ArrayProcessor {
  /**
   * 删除偶数下标元素
   * @param arr 输入数组
   * @param inPlace 是否原地修改
   * @returns 处理后的数组
   */
  static removeEvenIndexes<T>(arr: T[], inPlace: boolean = false): T[] {
    if (inPlace) {
      return this.removeEvenIndexesInPlace(arr)
    } else {
      return this.removeEvenIndexesNew(arr)
    }
  }
  
  private static removeEvenIndexesNew<T>(arr: T[]): T[] {
    return arr.filter((_, index) => index % 2 !== 0)
  }
  
  private static removeEvenIndexesInPlace<T>(arr: T[]): T[] {
    let writeIndex = 0
    for (let i = 0; i < arr.length; i++) {
      if (i % 2 !== 0) {
        arr[writeIndex] = arr[i]
        writeIndex++
      }
    }
    arr.length = writeIndex
    return arr
  }
  
  /**
   * 泛型方法:根据下标条件过滤数组
   */
  static filterByIndex<T>(
    arr: T[], 
    predicate: (index: number) => boolean
  ): T[] {
    return arr.filter((_, index) => predicate(index))
  }
}

// 使用示例
const numbers: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
const strings: string[] = ['a', 'b', 'c', 'd', 'e', 'f']

console.log(ArrayProcessor.removeEvenIndexes(numbers)) // [1, 3, 5, 7, 9]
console.log(ArrayProcessor.filterByIndex(strings, i => i % 2 === 0)) // ['a', 'c', 'e']
  1. 性能对比测试
javascript 复制代码
// 性能测试
function testPerformance() {
  const largeArray = Array.from({ length: 1000000 }, (_, i) => i)
  
  // 测试 filter 方法
  console.time('filter')
  const result1 = largeArray.filter((_, i) => i % 2 !== 0)
  console.timeEnd('filter')
  
  // 测试 for 循环
  console.time('for loop')
  const result2 = []
  for (let i = 1; i < largeArray.length; i += 2) {
    result2.push(largeArray[i])
  }
  console.timeEnd('for loop')
  
  // 测试 while 循环
  console.time('while loop')
  const arrCopy = [...largeArray]
  let i = 0
  while (i < arrCopy.length) {
    if (i % 2 === 0) {
      arrCopy.splice(i, 1)
    } else {
      i++
    }
  }
  console.timeEnd('while loop')
  
  // 测试 reduce
  console.time('reduce')
  const result4 = largeArray.reduce((acc, cur, i) => {
    if (i % 2 !== 0) acc.push(cur)
    return acc
  }, [])
  console.timeEnd('reduce')
}

testPerformance()
// 结果通常: for loop 最快, filter 次之, reduce 较慢, while+splice 最慢

总结

推荐方法:

  1. 最简洁filter方法

    css 复制代码
    arr.filter((_, i) => i % 2 !== 0)
  2. 最高性能for循环

    ini 复制代码
    const result = []
    for (let i = 1; i < arr.length; i += 2) {
      result.push(arr[i])
    }
  3. 原地修改:使用写指针

    ini 复制代码
    let writeIndex = 0
    for (let i = 0; i < arr.length; i++) {
      if (i % 2 !== 0) {
        arr[writeIndex] = arr[i]
        writeIndex++
      }
    }
    arr.length = writeIndex

注意事项:

  1. 索引从0开始:JavaScript 数组下标从0开始
  2. 避免splice :在循环中使用 splice会改变数组长度,容易出错
  3. 性能考虑 :大数据量时避免使用 splicefilter链式调用
  4. 不变性:根据需求选择是否修改原数组

扩展应用:

  • 删除奇数下标:i % 2 === 0
  • 删除特定模式:i % 3 === 0删除3的倍数下标
  • 保留特定范围:i >= 2 && i <= 5

**

相关推荐
困惑阿三5 小时前
2025 前端技术全景图:从“夯”到“拉”排行榜
前端·javascript·程序人生·react.js·vue·学习方法
苏瞳儿5 小时前
vue2与vue3的区别
前端·javascript·vue.js
weibkreuz6 小时前
收集表单数据@10
开发语言·前端·javascript
hboot7 小时前
别再被 TS 类型冲突折磨了!一文搞懂类型合并规则
前端·typescript
在西安放羊的牛油果7 小时前
浅谈 import.meta.env 和 process.env 的区别
前端·vue.js·node.js
鹏北海7 小时前
从弹窗变胖到 npm 依赖管理:一次完整的问题排查记录
前端·npm·node.js
布列瑟农的星空7 小时前
js中的using声明
前端
薛定谔的猫27 小时前
Cursor 系列(2):使用心得
前端·ai编程·cursor
用户904706683577 小时前
后端问前端:我的接口请求花了多少秒?为啥那么慢,是你慢还是我慢?
前端
深念Y7 小时前
仿B站项目 前端 4 首页 顶层导航栏
前端·vue·ai编程·导航栏·bilibili·ai开发