簡體   English   中英

如何使用 javascript Map() 函數創建對象

[英]How to create object using javascript Map() function

我正在學習 javascript 的Map()函數。 我想為declarativeNetRequest映射規則,但我需要一些幫助。

如何使用此模型作為輸出創建地圖

{
    "id" : 1,
    "priority": 1,
    "action" : { "type" : "block" },
    "condition" : {
        "urlFilter" : "abc",
        "domains" : ["foo.com"],
        "resourceTypes" : ["script"]
  }
}

目前,我正在從遠程服務器獲取過濾器列表,並使用此代碼對其進行解析,解析后我想將結果映射到一個可以與declarativeNetrequest api 一起使用的對象

let def = {};
let out;
let defMap = new Map();

const fetch = async () => {
  await axios({
  url: "https://raw.githubusercontent.com/easylist/easylist/master/easylist/easylist_adservers.txt",
  responseType: "text"
  })
  .then( (response) => {
      let parsed = response.data.split("\n");
    out = parsed.filter( (item) => {
      if( !item.startsWith("!") ){
        return item.replace(/([\|\|\w\d\.\^]+)(?:[\w-\?=~,\$]+)$.*/, "$1");
      }
    });
  });
  return out;
}
// debug only 
fetch().then( (out) => {
  console.log(out);
});

這可能嗎?

請參閱下面的示例,該示例根據規則輸出 JSON 對象列表。 以下是其他一些提示:

  • 您不需要Map() ,只需要一個常規的 JSON/Javascript 對象結構
  • 您不需要同時使用.then() (Promises 語法)和 await(異步/等待語法)-只需選擇一個-await 是處理異步響應的更現代的方法-我使用了 await
  • 如果您使用了.then() ,則 return 語句將在調用內部回調函數之前完成,因此不會設置out
  • 我沒有過多地研究文件的語法 - 但我認為 ^ 之后的片段很有用,也許只將它們應用於某些子域
  • 阻止規則接受一組域 - 因此您可以創建一個適用於多個域的規則,而不是每個域的一個規則
import axios from 'axios'

async function fetch() {
  const resp = await axios({
    url: "https://raw.githubusercontent.com/easylist/easylist/master/easylist/easylist_adservers.txt",
    responseType: "text"
  })
  return [...parseDomains(resp.data)].map(blockRule)
}

function* parseDomains(data) {
  for (const line of data.split("\n")) {
    const match = line.match(/^[\|]+(?<domain>[^\^]+)/)
    if (match) yield match.groups.domain
  }
}

function blockRule(domain, id) {
  return {
    id,
    priority: 1,
    action: { type: "block" },
    condition: {
      urlFilter: `for_${domain}`,
      domains: [domain],
      resourceTypes: ["script"]
    }
  }
}

// debug only 
fetch().then((out) => {
  console.log(out)
})

補充說明:

  1. 獲取數據:
resp = await axios(...)
  1. parseDomains將數據拆分為多行(如您之前所做的那樣),並對其進行正則表達式匹配。 如果匹配,它將yield另一個域。 function*使它成為一個生成器表達式 - 基本上它可以迭代(就像一個數組)元素是你yield任何東西。 如果每一行都會產生一個域,那么您可以使用.map()將每一行轉換為一個域,但只有某些行會產生域,因此您需要其他東西。 另一種方法是創建一個空數組,然后每次找到有效域時向其中添加一個新域元素。

正則表達式本身比您擁有的要簡單一些:

  • 匹配一個或多個 | 的
  • 后跟一個或多個非 ^(因此將在遇到 ^ 或字符串結尾時結束/終止) - 將其放入匹配組(用括號括起來,就像您所做的那樣)並給出名稱domain
  • 如果返回值match為真,則表示您找到了匹配項,並且可以在match.groups找到匹配match.groups - 因為我將其命名為domain所以它在match.groups.domain
  1. 由於parseDomains是一個生成器表達式,它是惰性求值的,要在其上運行映射/過濾器,您需要急切地求值它 - 這就是[...expr]所做的 - 它基本上強制對生成器表達式進行求值和轉換成一個數組。 我們可以繼續像這樣懶惰地評估事情:
async function* fetch() {
  const resp = await axios(...)
  for (const domain of parseDomains(resp.data)
    yield blockRule(domain)
}
  1. 最后,我們通過 blockRule 映射域以輸出實際規則,因此您最終將擁有一個規則對象數組。

暫無
暫無

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

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