【前端js】算法全歸納(一)數組:最全數組操作合集


本文主要從應用來講數組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可選。規定排序順序。必須是函數。

  1. 如果調用該方法時沒有使用參數,將按照字符編碼的順序進行排序。要實現這一點,首先應把數組的元素都轉換成字符串(如有必要),以便進行比較。
  2. 如果想按照其他標準進行排序,就需要提供比較函數,該函數要比較兩個值,然後返回一個用於說明這兩個值的相對順序的數字。比較函數應該具有兩個參數 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 數組上進行操作,並將結果返回

思路

  1. 特殊情況,空數組,但數組
  2. 爲了避免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,結果返回新的數組
思路

  1. 使用splice插入元素,因爲splice修改願數組,所以需要先拷貝數組;
  2. 因爲splice返回的是被刪除的元素,所以需要先調用方法,再返回拷貝數組,不能直接返回splice的結果
function insert(arr, item, index) {
    var res = arr.slice(0);
    res.splice(index,0,item);
    return res;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章