文章目錄
本文主要從應用來講數組api的一些操作,如一行代碼扁平化n維數組、數組去重、求數組最大值、數組求和、排序、對象和數組的轉化等。
1.扁平化n維數組
1.簡單方法(牛客網不支持)
ES10扁平數組的api, n表示維度, n值爲 Infinity時維度爲無限大。
Array.flat(n)
[1,[2,3]].flat(2) //[1,2,3]
[1,[2,3,[4,5]].flat(3) //[1,2,3,4,5]
[1[2,3,[4,5[...]].flat(Infinity) //[1,2,3,4...n]
2.兼容方法
先判斷是否有嵌套數組,有的情況下,...arr
展開操作每次能去除一層嵌套數組,直到去除掉所有嵌套數組爲止
function flatten(arr) {
while (arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
flatten([1, [2, 3]]); //[1,2,3]
flatten([1, [2, 3, [4, 5]]]); //[1,2,3,4,5]
2.去重
1.簡單方法(不能對嵌套數組,對象數組去重)
利用集合set不重複的特性:set是ES6新出來的一種一種定義不重複數組的數據類型
Array.from
是將類數組轉化爲數組
...
是擴展運算符,將set裏面的值轉化爲arg1,arg2,arg3
(類似數組的toString
)
Array.from(new Set([1,2,3,3,4,4])) //[1,2,3,4]
[...new Set([1,2,3,3,4,4])] //[1,2,3,4]
2.兼容方法(可以對嵌套數組,對象數組去重)
let obj = {};//對照對象
for (var i = 0; i < result2.length; i++) {
// 判斷當前項是否遍歷過,是則刪除,否存入obj以作對照
if (obj[result2[i]]) {
result2.splice(i, 1);
i--; //數組刪除了一項,要把i回退一下,不然會跳過下一項不去遍歷
} else {
obj[result2[i]] = 1;
}
}
3.排序
1.簡單方法
arrayObject.sort(sortby)
sortby可選。規定排序順序。必須是函數。
- 如果調用該方法時沒有使用參數,將按照字符編碼的順序進行排序。要實現這一點,首先應把數組的元素都轉換成字符串(如有必要),以便進行比較。
- 如果想按照其他標準進行排序,就需要提供比較函數,該函數要比較兩個值,然後返回一個用於說明這兩個值的相對順序的數字。比較函數應該具有兩個參數 a 和 b,函數返回值大於0的時候,交換ab的位置,a排在b的後面。
[1,2,3,4].sort(); // [1, 2,3,4],默認是升序
[1,2,3,4].sort((a, b) => b - a); // [4,3,2,1] 降序
2.兼容方法
冒泡排序
快速排序
選擇排序
4.最大值
1.簡單方法
方法一:max()
Math.max(n1,n2,n3,...,nX)
max() 方法可返回兩個指定的數中帶有較大的值的那個數
n1,n2,n3,…,nX 可選。1 或多個值。在 ECMASCript v3 之前,該方法只有兩個參數。
返回值:參數中最大的值。如果沒有參數,則返回 -Infinity。如果有某個參數爲 NaN,或是不能轉換成數字的非數字值,則返回 NaN。
http://www.runoob.com/jsref/jsref-max.html
Math.max(...[1,2,3,4]) //4
Math.max.apply(this,[1,2,3,4]) //4
方法二:reduce()
迭代比較(兼容max方法只支持兩個參數的情況)
reduce是ES5的數組api,參數有函數和默認初始值;
函數有四個參數,pre(上一次的返回值),cur(當前值),curIndex(當前值索引),arr(當前數組)
[1,2,3,4].reduce((prev, cur)=> (
Math.max(prev,cur))
,0)//4
例題
/**第一題
* 說明:獲取一個數字數組中的最大值
* 示例:
* 輸入:[1, 5, 3, 9, 2, 7]
* 輸出:9
*/
var arr = [1, 5, 3, 9, 2, 7];
//方法一
Math.max(...arr);//9
//方法二
Math.max.apply(this,arr);//9
Math.max.call(this,...arr);//9
//方法三
arr.reduce((prev, cur)=> (
Math.max(prev,cur))
,0)//9
5.打亂順序
//添加原型方法
Solution.prototype.shuffle = function() {
//交換數組元素順序
const swap = (a, i, j) => {
[a[i], a[j]] = [a[j], a[i]];
};
let arr = this.nums.slice(); //深拷貝數組,不然會改變this.nums,影響reset的輸出
for (let i = arr.length - 1; i >= 0; i--) {//從後往前遍歷數組
//swap(arr, i, Math.floor(Math.random() * (arr.length - i + 1))); //每次
swap(arr, i, Math.floor(Math.random() * i+1));//交換i和0-i中隨機位置的元素
}
return arr;
};
參考 https://segmentfault.com/a/1190000018549643
6. 移除數組中的元素(牛客網-js能力測評)
題目
移除數組 arr 中的所有值與 item 相等的元素,直接在給定的 arr 數組上進行操作,並將結果返回
思路
特殊情況
,空數組,但數組- 爲了避免
splice
方法影響接下來的遍歷,從後往前
遍歷數組
function removeWithoutCopy(arr, item) {
if (arr.length === 0) return []; //空數組
if (arr.length === 1) return item === arr[0] ? arr : []; //單個元素數組
for (var i = arr.length - 1; i >= 0; i--) {
//從後往前遍歷,每次刪除以後不用重新修改i
arr[i] === item ? arr.splice(i, 1) : "";
}
return arr;
}
7. 數組首尾添加元素(牛客網-js能力測評)
題目1
在數組 arr 末尾添加元素 item。不要直接修改數組 arr,結果返回新的數組
.concat()
方法會返回一個新數組
function append(arr, item) {
return arr.concat(item);
}
題目2
在數組 arr 開頭添加元素 item。不要直接修改數組 arr,結果返回新的數組
注意添加的順序:
function prepend(arr, item) {
return [].concat(item,arr);
}
8. 數組首尾刪除元素(牛客網-js能力測評)
題目1
刪除數組 arr 最後一個元素。不要直接修改數組 arr,結果返回新的數組
思路
1.使用不修改原數組的刪除api——slice
2.使用修改原數組的刪除api——splice/pop/shift
,爲了不修改原來的數組,需要先拷貝數組arr.slice(0),from,[...arr]
都可以實現深拷貝
3. .pop()
方法返回的是出棧元素,這裏要求返回修改後的數組
function truncate(arr) {
var res = arr.slice(0);
res.pop();
return res;
}
題目2
刪除數組 arr 第一個元素。不要直接修改數組 arr,結果返回新的數組
function curtail(arr) {
return arr.slice(1);
}
9.插入元素(牛客網-js能力測評)
題目
在數組 arr 的 index 處添加元素 item。不要直接修改數組 arr,結果返回新的數組
思路
- 使用splice插入元素,因爲splice修改願數組,所以需要先拷貝數組;
- 因爲splice返回的是被刪除的元素,所以需要先調用方法,再返回拷貝數組,不能直接返回splice的結果
function insert(arr, item, index) {
var res = arr.slice(0);
res.splice(index,0,item);
return res;
}