首頁 >web前端 >js教程 >稍微好一點的「地圖」可以讓你更輕鬆地到達那裡...

稍微好一點的「地圖」可以讓你更輕鬆地到達那裡...

Barbara Streisand
Barbara Streisand原創
2024-12-09 08:33:12373瀏覽

A slightly better

在 JavaScript 中,Map 是一個非常有用的內建類,它在鍵和值之間建立 O(1) 查找。

const myMap = new Map()

for(const file of files) {
    const [,extension] = file.name.split(".")
    if(!myMap.has(extension)) {
        myMap.set(extension, [])
    }
    myMap.get(extension).push(file)
}

您可以使用地圖來完成您可能經常做的各種事情:

  • 建立資料分組列表,如上面按檔案副檔名分組的範例

  • 聚合數據,例如對一系列鍵的值進行計數或求和

// 1) Counting occurrences
const items = ['apple','apple','orange','banana','apple'];
const counts = new Map();
for (const item of items) {
  counts.set(item, (counts.get(item) || 0) + 1);
}
  • 建立在後續步驟中使用的快速查找
const users = [
  {id:1,name:'A',role:'admin'},
  {id:2,name:'B',role:'user'},
  {id:3,name:'C',role:'user'}
];
const userMap = new Map();
for (const u of users) {
  userMap.set(u.id, u);
}

Map 優於使用簡單物件 ({}),原因有幾個,只要您不必使用 stringify 儲存結果:

  • 它可以用非字串的鍵
  • 即使您使用字串鍵,它也比物件稍快

但是,如果您儲存在映射中的物件需要構造(從簡單數組到複雜物件),則可能會有很多樣板檔案和混合問題,這需要散佈在使用它的程式碼中.

const map = new Map()

for(const item of items) {
   if(!map.has(item.type)) {
       const newType = new Type(item.type, getInfoForType(item.type))
       map.set(item.type, newType)
   }
   map.get(item.type).doSomething(item)

}

這個「可以」是可以的,但如果你需要在多個地方更新或初始化值,那麼保持 DRY 就變得更困難。

出於這個原因,我使用了MapPlus 類,它是Map 的擴展,它提供了一個缺失的鍵初始化函數,可以將其提供給構造函數,或者如果初始化程序確實需要上下文信息之外的信息,則可以將其作為get 的第二個參數鑰匙。

class MapPlus extends Map {
    constructor(missingFunction) {
        super()
        this.missingFunction = missingFunction
    }

    get(key, createIfMissing = this.missingFunction) {
        let result = super.get(key)
        if (!result && createIfMissing) {
            result = createIfMissing(key)
            if (result && result.then) {
                const promise = result.then((value) => {
                    super.set(key, value)
                    return value
                })
                super.set(key, promise)
            } else {
                super.set(key, result)
            }
        }
        return result
    }
}

有了這個你就可以做這樣的事情:

const map = new MapPlus(()=>[])

for(const item of items) {
    map.get(item.type).push(item)
}

就像缺少鍵一樣,它只會產生一個空數組。

我經常需要兩個級別,所以我將像這樣定義地圖:

const map = new MapPlus(()=>new MapPlus(()=>[]))
for(const item of items) {
   map.get(item.type).get(item.subType).push(item)
}

建構函式確實取得了正在使用的金鑰,因此我們也可以這樣做:

const map = new MapPlus((type)=>new Type(type, getInfoForType(type))

for(const item of items) {
    map.get(item.type).doSomething(item)
}

以上是稍微好一點的「地圖」可以讓你更輕鬆地到達那裡...的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn