JavaScript列表獲取指定范圍值的N種方法
前言
在日常開發(fā)中,我們經(jīng)常需要從數(shù)組中提取指定范圍的值。比如獲取最近7天的數(shù)據(jù)、提取表格中D列到F列的內(nèi)容、截取數(shù)組中間一段做分析等等。
看似簡單的需求,其實有 N 種實現(xiàn)方式!今天就來總結(jié)一下 JS 中獲取數(shù)組指定范圍值的所有方法,從最老的語法到最新的 ES2023 特性,一網(wǎng)打盡!??
方法一覽
| 序號 | 方法 | 是否修改原數(shù)組 | 兼容性 | 推薦度 | 代碼量 |
|---|---|---|---|---|---|
| 1 | slice(start, end) ? | ? 不修改 | ? IE9+ | ????? | 1行 |
| 2 | splice(start, count) | ? 修改 | ? IE4+ | ??? | 1行 |
| 3 | for + if 手動截取 | ? 不修改 | ? IE6+ | ???? | 5行 |
| 4 | filter() + 索引 | ? 不修改 | ? ES5+ | ??? | 1行 |
| 5 | reduce() 累積 | ? 不修改 | ? ES5+ | ?? | 2行 |
| 6 | at() + 循環(huán)(ES2022) | ? 不修改 | ? ES2022+ | ???? | 1行 |
方法詳解
方法1:slice(start, end)????? 最推薦
這是 最常用、最簡潔 的方法,左閉右開,不會修改原數(shù)組!
const list = [10, 20, 30, 40, 50, 60, 70]; // ? 提取索引 2 到 5(不包含5) const sub1 = list.slice(2, 5); console.log(sub1); // [30, 40, 50] // ? 提取索引 3 到末尾 const sub2 = list.slice(3); console.log(sub2); // [40, 50, 60, 70] // ? 使用負(fù)數(shù)索引(從末尾開始) const sub3 = list.slice(-4, -1); console.log(sub3); // [40, 50, 60] // ? 提取最后一個元素(等同于 at(-1)) const sub4 = list.slice(-1); console.log(sub4[0]); // 70
關(guān)鍵規(guī)則:
| 規(guī)則 | 說明 | 示例 |
|---|---|---|
slice(start, end) | 左閉右開,包含 start,不包含 end | slice(2,5) → 索引 2,3,4 |
slice(start) | 從 start 到末尾 | slice(3) → 索引 3,4,5… |
slice(-3) | 倒數(shù)第3個到末尾 | slice(-3) → 最后3個 |
slice(-4,-1) | 倒數(shù)第4個到倒數(shù)第1個(不含) | → 倒數(shù)第4,3,2個 |
start >= end | 返回空數(shù)組 | slice(5,2) → [] |
底層原理:slice() 是淺拷貝,對于嵌套數(shù)組/對象,內(nèi)部引用仍指向原數(shù)據(jù)。
方法2:splice(start, count)??? 會修改原數(shù)組!
splice() 會刪除并返回指定范圍的元素,原數(shù)組會被修改!
const list = [10, 20, 30, 40, 50]; // ? 從索引1開始,刪除3個元素 const removed = list.splice(1, 3); console.log(removed); // [20, 30, 40] console.log(list); // [10, 50] ?? 原數(shù)組被改了!
適用場景:需要同時刪除并獲取元素時使用。
| 方法 | 用途 | 是否修改原數(shù)組 |
|---|---|---|
slice(start, end) | 提取范圍(只讀) | ? 不修改 |
splice(start, count) | 刪除范圍(可寫) | ? 修改 |
方法3:for+if手動截取 ???? 兼容老瀏覽器
如果需要復(fù)雜條件判斷(比如排除空行),用手動循環(huán)最靈活!
const list = [10, 20, 30, 40, 50, 60, 70];
const result = [];
// ? 提取索引 2 到 5 的元素
for (let i = 2; i < 5; i++) {
result.push(list[i]);
}
console.log(result); // [30, 40, 50]
// ? 提取索引 3 到末尾
for (let i = 3; i < list.length; i++) {
result.push(list[i]);
}
console.log(result); // [40, 50, 60, 70]
實戰(zhàn)案例:排除空行數(shù)據(jù)(JS宏場景)
// 讀取表格數(shù)據(jù),排除空行
function getTableData(sheetData) {
let results = [];
// 從第1行開始(跳過表頭)
for (let i = 1; i < sheetData.length; i++) {
let rowData = sheetData[i].slice(0, 3); // 提取前3列
// 正則判斷是否全是空白字符
if (!/^[\s]*$/.test(rowData.join(''))) {
results.push(rowData);
}
}
return results.length > 0 ? results : "";
}
正則 /^[\s]*$/ 解析:^ 開頭,[\s]* 零個或多個空白字符,$ 結(jié)尾 → 整行都是空白
方法4:filter()+ 索引判斷 ??? 函數(shù)式風(fēng)格
const list = [10, 20, 30, 40, 50, 60, 70]; // ? 提取索引 2 到 5 的元素 const sub = list.filter((_, index) => index >= 2 && index < 5); console.log(sub); // [30, 40, 50] // ? 提取倒數(shù)3個元素 const last3 = list.filter((_, index) => index >= list.length - 3); console.log(last3); // [50, 60, 70]
優(yōu)點:代碼簡潔,函數(shù)式風(fēng)格
缺點:性能略差(需要遍歷整個數(shù)組)
方法5:reduce()累積 ?? 函數(shù)式編程
const list = [10, 20, 30, 40, 50, 60, 70];
// ? 提取索引 2 到 5 的元素
const sub = list.reduce((acc, cur, i) => {
if (i >= 2 && i < 5) acc.push(cur);
return acc;
}, []);
console.log(sub); // [30, 40, 50]
優(yōu)點:函數(shù)式編程,適合鏈?zhǔn)秸{(diào)用
缺點:代碼復(fù)雜,性能一般
方法6:at()+ 循環(huán)(ES2022)???? 語義最清晰
ES2022 新增的 at() 支持負(fù)數(shù)索引,語義最清晰!
const list = [10, 20, 30, 40, 50, 60, 70];
// ? 提取最后3個元素
const last3 = [list.at(-3), list.at(-2), list.at(-1)];
console.log(last3); // [50, 60, 70]
// ? 通用函數(shù):提取任意范圍
function getRange(arr, start, end) {
const result = [];
for (let i = start; i < end; i++) {
result.push(arr.at(i));
}
return result;
}
console.log(getRange(list, 2, 5)); // [30, 40, 50]
| 方法 | 正序索引 | 逆序索引 | 示例 |
|---|---|---|---|
arr[i] | ? arr[0] | ? 不支持 | arr[0] → 10 |
arr.at(i) | ? arr.at(0) | ? arr.at(-1) | arr.at(-1) → 70 |
性能對比(100萬次循環(huán))
| 方法 | 耗時 | 性能排名 | 推薦度 |
|---|---|---|---|
slice(start, end) | ~15ms | ?? 第1名 | ????? |
for + push | ~18ms | ?? 第2名 | ???? |
at() + 循環(huán) | ~20ms | ?? 第3名 | ???? |
filter() | ~80ms | 第4名 | ??? |
reduce() | ~120ms | 第5名 | ?? |
splice() | ~25ms | 第6名(但會修改) | ??? |
結(jié)論:slice() 性能最好,for 循環(huán)緊隨其后,函數(shù)式方法稍慢但代碼優(yōu)雅!
安全寫法(防止越界)
const list = [10, 20, 30];
// ? 不安全:end 超出范圍會返回到末尾,但 start 超出會返回空數(shù)組
const sub1 = list.slice(5, 10); // []
// ? 安全寫法:限制范圍
function safeSlice(arr, start, end) {
start = Math.max(0, start);
end = Math.min(arr.length, end);
return arr.slice(start, end);
}
console.log(safeSlice(list, 1, 10)); // [20, 30]
實戰(zhàn)場景
場景1:獲取最近7天數(shù)據(jù)
const prices = [10.5, 20.3, 15.8, 12.1, 18.9, 22.5, 19.8, 25.3, 28.7, 30.2]; // ? 提取最近7天 const last7 = prices.slice(-7); console.log(last7); // [18.9, 22.5, 19.8, 25.3, 28.7, 30.2]
場景2:提取表格指定列(JS宏)
// 提取 D列 到 F列(索引3到6,左閉右開) const fangwei = [3, 6]; const colData = sheetData[i].slice(fangwei[0], fangwei[1]); // D列索引=3, F列索引=5, slice(3,6) → 索引3,4,5 → D,E,F列
場景3:排除空行后提取范圍
const rawData = [ [10, 20, 30], [], // 空行 [40, 50, 60], null, // 空行 [70, 80, 90] ]; const filtered = rawData.filter(row => row && row.length > 0); const result = filtered.slice(1, 3); // 提取第2到第3行 console.log(result); // [[40, 50, 60]]
封裝通用函數(shù)
/**
* 獲取數(shù)組指定范圍的值
* @param {Array} arr - 原數(shù)組
* @param {Number} start - 起始索引(支持負(fù)數(shù))
* @param {Number} end - 結(jié)束索引(不包含,支持負(fù)數(shù),可省略)
* @returns {Array} 范圍內(nèi)的值
*/
function getRange(arr, start, end) {
if (end === undefined) {
return arr.slice(start); // 從 start 到末尾
}
return arr.slice(start, end);
}
// 使用示例
const list = [10, 20, 30, 40, 50, 60, 70];
console.log(getRange(list, 2, 5)); // [30, 40, 50]
console.log(getRange(list, -3)); // [50, 60, 70]
console.log(getRange(list, -4, -1)); // [40, 50, 60]
最終推薦
| 場景 | 推薦方法 | 代碼 |
|---|---|---|
| ? 通用場景(首選) | slice(start, end) | arr.slice(2, 5) |
| ? 現(xiàn)代項目(ES2022+) | at() + 循環(huán) | arr.at(i) |
| ? 兼容老瀏覽器 | for + push | 手動循環(huán) |
| ? 需要刪除原數(shù)據(jù) | splice(start, count) | arr.splice(2, 3) |
| ? 函數(shù)式風(fēng)格 | filter() | arr.filter((_,i)=>i>=2&&i<5) |
| ? 不推薦 | reverse()[0] 等 | 會修改原數(shù)組 |
總結(jié)表格(6種方法)
| 序號 | 方法 | 修改原數(shù)組 | 兼容性 | 性能 | 推薦指數(shù) |
|---|---|---|---|---|---|
| 1 | slice(start, end) | ? | IE9+ | ?? | ????? |
| 2 | splice(start, count) | ? | IE4+ | ?? | ??? |
| 3 | for + if | ? | IE6+ | ?? | ???? |
| 4 | filter() | ? | ES5+ | 第4名 | ??? |
| 5 | reduce() | ? | ES5+ | 第5名 | ?? |
| 6 | at() + 循環(huán) | ? | ES2022+ | ?? | ???? |
一句話總結(jié)
萬能首選:slice(start, end) —— 不修改原數(shù)組、性能最優(yōu)、兼容性好!
語義最清晰:at(index) —— 正負(fù)索引都支持,一看就懂!
最靈活:for + if —— 復(fù)雜條件判斷的不二之選!
以上就是JavaScript列表獲取指定范圍值的N種方法的詳細內(nèi)容,更多關(guān)于JavaScript列表獲取指定范圍值的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS實現(xiàn)transform實現(xiàn)扇子效果
這篇文章主要為大家詳細介紹了JS實現(xiàn)transform實現(xiàn)扇子效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-01-01
微信二次分享報錯invalid signature問題及解決方法
基于微信公眾號開發(fā)的h5頁面(使用jssdk接口),由用戶A分享給用戶B,用戶B再次分享這個頁面時,不能成功分享。這篇文章主要介紹了微信二次分享報錯invalid signature問題及解決方法,需要的朋友可以參考下2019-04-04
如何解決java.lang.NumberFormatException: null異常
這篇文章主要介紹了如何解決java.lang.NumberFormatException: null異常問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03

