JavaScript 陣列常見操作 (二)

程式設計三昧發表於2022-02-06

陣列常見操作.001

前言

陣列是 JavaScript 中常見資料型別之一,關於它的一些操作方法,我在這裡做一下簡單記錄和總結。

今天主要介紹:

  • 如何找出陣列中的重複/非重複元素
  • 陣列扁平化方法

找出陣列中的重複元素或非重複元素

雙重迴圈 + slice,找出重複的元素。雖然只要求找出重複元素,但應該注意要順便去重,否則外迴圈還是會對重複元素進行一遍檢查;用 flag 記錄重複次數,只在第一次重複的時候將元素放入新陣列

function search(arr){
    let res = []
    let flag = 0
    for(let i = 0;i < arr.length;i++){
        for(let j = i+1;j<arr.length;j++){
            if(arr[i] === arr[j]){
                flag++
                if(flag == 1) res.push(arr[i])
                arr.splice(j,1)
            }    
        }
        flag = 0
    }
    return res
}

map + filter,記錄每個元素出現的次數。有了重複次數,就可以篩選出重複元素、重複次數最多元素或者非重複元素:

function search(arr){
    const map = new Map()
    for(item of arr){
        if(!map.has(item)){
            map.set(item,1)
        } else {
            map.set(item,map.get(item)+1)
        }
    }
    // 找出重複元素,即出現次數大於1
    return [...map.entries()].filter(item => item[1] > 1).map(item => item[0])
    // 找出非重複元素,即出現次數等於1
    return [...map.entries()].filter(item => item[1] == 1).map(item => item[0])
    // 找出重複次數最多的元素
    return [...map.entries()]
        .filter(item => item[1] == Math.max(...map.values()))
        .map(item => item[0])
}

陣列扁平化 / 陣列降維

二維陣列,以 [[],[{a:1}],[],[3,4],5] 為例,降維後得到 [{a:1},3,4,5]

二維陣列:雙重迴圈

需要檢查是否每個元素都是陣列

function flatten(arr){
    const res = []
    for(let i = 0;i < arr.length; i++){
        if(Array.isArray(arr[i])){
            for(let j = 0;j < arr[i].length;j++){
                res.push(arr[i][j])
            }            
        } else {
            res.push(arr[i])
        }      
    }
    return res
}

二維陣列:迴圈 + concat

concat 本身就可以給陣列降維一次

function reduceDiemension(arr){
    const res = []
    for(let i = 0;i < arr.length;i++){
        res = res.concat(arr[i])
    }
    return res
}

二維陣列:reduce + concat

上面的過程本身是一種歸併,所以考慮使用 reduce

function flatten(arr){
    return arr.reduce((acc,cur) => acc.concat(cur),[])
}

二維陣列:展開 / apply + concat

透過展開原陣列或者將其作為 apply 的第二個引數,把陣列轉化為一個引數列表

function flatten(arr){
    // return [].concat([],arr)
    return [].concat(...arr)
}

多維陣列,以下面的陣列為例:

const arr = [
    1,
    [
        2,[3],
        [4,5,6],
        [7,8,9],
        10,11
    ],
    12,
    13,
    [15,16,17]
]

降維後得到 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17]

多維陣列:toString + split

陣列降維可以看作是把所有的括弧都去掉,而陣列的 toString 方法剛好可以做這個事,之後再呼叫字串的 split 把字串轉換回陣列即可。但這個方法很侷限,要求陣列元素的資料型別都相同。

function flattern_numberArray(arr){
    return arr.toString().split(",").map(x => Number)
}

多維陣列:forEach + 遞迴

function flatten(arr){
    const res = []
    arr.forEach(item => {
        if(Array.isArray(item)){
            flatten(item)
        } else {
            res.push(item)
        }
    })
    return res
}

多維陣列:reduce + 遞迴

同理,上面的過程是一種歸併,可以使用 reduce 完成。需要注意的是,reduce 的回撥函式必須返回一個陣列,所以不要再用 push 了

function flatten(arr){
    return arr.reduce((acc,cur) => {
        if(Array.isArray(cur)){
            return [...acc , ...flatten(cur)]    
        } else {
            return [...acc,cur]
        }
    },[])
}

多維陣列:while + some

只要陣列中還有陣列,就使用 concat 給這個陣列降維。這個方法可以不使用遞迴

function flatten(arr){    
    while(arr.some(item => Array.isArray(item))){
        arr = [].concat(...arr)
    }
    return arr
}

不確定維數的陣列: flat

陣列降維,直接用之前講過的 flat 是最簡單的。預設傳參 1,表示降維一次;可以傳參 Infinity,實現完全降維,最終得到一個一維陣列。

~

~ 本文完,感謝閱讀!

~

學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!

大家好,我是〖程式設計三昧〗的作者 隱逸王,我的公眾號是『程式設計三昧』,歡迎關注,希望大家多多指教!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章