[英]How to create object using javascript Map() function
I'm learning Map()
function of javascript.我正在学习 javascript 的
Map()
函数。 I want to map rules for declarativeNetRequest
but I need a bit of help.我想为
declarativeNetRequest
映射规则,但我需要一些帮助。
How I can create a map using this model as output:如何使用此模型作为输出创建地图:
{
"id" : 1,
"priority": 1,
"action" : { "type" : "block" },
"condition" : {
"urlFilter" : "abc",
"domains" : ["foo.com"],
"resourceTypes" : ["script"]
}
}
At the moment I'm fetching a list of filters from a remote server and I'm parsing it using this code, after the parsing I want to map the results to have an object that I can use with declarativeNetrequest
api目前,我正在从远程服务器获取过滤器列表,并使用此代码对其进行解析,解析后我想将结果映射到一个可以与
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);
});
will be this possible?这可能吗?
See below example that outputs a list of JSON objects based on the rules.请参阅下面的示例,该示例根据规则输出 JSON 对象列表。 Here are some other pointers:
以下是其他一些提示:
Map()
, just a regular JSON/Javascript object structureMap()
,只需要一个常规的 JSON/Javascript 对象结构.then()
(Promises syntax) and await (async/await syntax) together - just chose one - await is the more modern way to deal with asynchronous responses - I used await.then()
(Promises 语法)和 await(异步/等待语法)-只需选择一个-await 是处理异步响应的更现代的方法-我使用了 await.then()
, then the return statement would have completed before the inner callback function had been called, so out
would not have been set.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)
})
Additional explanation:补充说明:
resp = await axios(...)
parseDomains
splits the data into lines (as you did before), and does a regular expression match on it. parseDomains
将数据拆分为多行(如您之前所做的那样),并对其进行正则表达式匹配。 If it matches, it'll yield
another domain.yield
另一个域。 The function*
makes this a generator expression - basically it can be iterated over (like an array) the elements are whatever you yield
. function*
使它成为一个生成器表达式 - 基本上它可以迭代(就像一个数组)元素是你yield
任何东西。 If each line would yield a domain then you could have used .map()
to convert each line to a domain, but only some lines yield domains so you need something else..map()
将每一行转换为一个域,但只有某些行会产生域,因此您需要其他东西。 An alternative would have been to create an empty array and then add a new domain element to it each time you found a valid domain. The regular expression itself is a bit simpler than the one you had:正则表达式本身比您拥有的要简单一些:
domain
domain
match
is truthy, it means you have found a match, and the matches can be found in match.groups
- since I named it domain
it's in match.groups.domain
match
为真,则表示您找到了匹配项,并且可以在match.groups
找到匹配match.groups
- 因为我将其命名为domain
所以它在match.groups.domain
parseDomains
is a generator expression, which are lazily evaluated, to run a map/filter on it you'll need to eagerly evaluate it - that's what [...expr]
does - it basically forces the generator expression to be evaluated and converted into an array.parseDomains
是一个生成器表达式,它是惰性求值的,要在其上运行映射/过滤器,您需要急切地求值它 - 这就是[...expr]
所做的 - 它基本上强制对生成器表达式进行求值和转换成一个数组。 We could have kept evaluating things lazily like this instead:async function* fetch() {
const resp = await axios(...)
for (const domain of parseDomains(resp.data)
yield blockRule(domain)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.