簡體   English   中英

如何過濾 JavaScript 地圖?

[英]How to filter a JavaScript Map?

給定一個 ES6 映射和謂詞函數,我如何安全地刪除映射的所有不匹配元素?


我找不到官方的 API 函數,但我可以想到兩個實現。 第一個不嘗試就地刪除,而是創建一個副本:

 // version 1: function filter(map, pred) { const result = new Map(); for (let [k, v] of map) { if (pred(k,v)) { result.set(k, v); } } return result; } const map = new Map().set(1,"one").set(2,"two").set(3,"three"); const even = filter(map, (k,v) => k % 2 === 0); console.log([...even]); // Output: "[ [ 2, 'two' ] ]"

另一個就地刪除。 在我的測試中,它可以工作,但我沒有發現修改地圖不會破壞迭代器(for-of 循​​環)的保證:

 // version 2: function deleteIfNot(map, pred) { for (let [k, v] of map) { if (!pred(k,v)) { map.delete(k); } } return map; } const map = new Map().set(1,"one").set(2,"two").set(3,"three"); deleteIfNot(map, (k,v) => k % 2 === 0); console.log([...map]); // Output: "[ [ 2, 'two' ] ]"

問題:

  • 第二個版本(就地刪除)在所有平台上都正確嗎?
  • 有沒有更好的方法來實現就地過濾器? 也許我錯過了一些官方 API?

如果我們想對地圖使用.filter()迭代器,我們可以應用一個簡單的技巧,因為 ES6 地圖沒有 .filter 運算符。 Axel Rauschmayer 博士的方法是:

  • 將映射轉換為 [key, value] 對的數組。
  • 映射或過濾數組。
  • 將結果轉換回地圖。

例子:

 const map0 = new Map([ ['a', 1], ['b', 2], ['c', 3] ]); const map1 = new Map( [...map0] .filter(([k, v]) => v < 3 ) ); console.info([...map1]); //[0: ["a", 1], 1: ["b", 2]]

當一個條目在循環中被刪除時,ES6 迭代沒有問題。

沒有特殊的 API 可以有效地過濾 ES6 映射條目而無需對其進行迭代。

如果地圖不必是不可變的並且應該就地修改,則在過濾時創建新地圖會產生開銷。

還有 Map forEach ,但它假定也將使用該值。

由於地圖僅按其鍵過濾,因此條目對象沒有用處。 可以通過迭代映射鍵來改進它:

for (let k of map.keys()) {
  if (!(k % 2))
    map.delete(k);
}

我學到的一個優雅的答案。

// MAP EXAMPLE
const myMap = {
  "1G7JA": {
    id: 1,
    name: "Jack"
  },
  "H7GA0": {
    id: 2,
    name: "Betty"
  },
  "8JK12": {
    id: 3,
    name: "Mary"
  }
};

// CONVERT MAP TO ARRAY
const myArray = Object.values(myMap).filter(report=> report.user._id === userId);

// CONVERT ARRAY TO MAP
const arrayToMap = (array, element) => {
  const result = {};
  array.forEach(item => {
    result[Object.byString(item, element)] = item;
  });
  return result;
};

但是,您正在將地圖轉換為易於過濾的數組(很多處理)。 它適得其反,僅在小型陣列上使用,在這種情況下,需要將列表保留為對象超出了使用此陣列的原因。

問候

丹尼爾

// Given a map with keys a, b

const m = new Map()
m.set('a', 1)
m.set('b', 2)

// Return a new map that do not match key a

new Map([...m].filter(([k, v])=>k!=='a'))

// Return a new map only matching value 2

new Map([...m].filter(([k, v])=>v===2))

// Filter in place, removing all values not 2

[...m].map((i)=>i[1]!==2 && m.delete(i[0]))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM