有没有比非常写匹配更好的方法?
Is there better way than write match very much?
嗨,
我有这个代码
let key = N001DSC29MC22HC22DD04MD09YD21
function get(key) {
let res = {};
res.matchNumber = key.match(/(?<=N)\d{3}/g);
res.matchSeconds = key.match(/(?<=DSC)\d{2}/g);
res.matchMinutes = key.match(/(?<=MC)\d{2}/g);
res.matchHours = key.match(/(?<=HC)\d{2}/g);
res.matchDay = key.match(/(?<=DD)\d{2}/g);
res.matchMonth = key.match(/(?<=MD)\d{2}/g);
res.matchYear = key.match(/(?<=YD)\d{2}/g);
res.title = JSON.parse(localStorage.getItem(key)).title;
res.description = JSON.parse(localStorage.getItem(key)).description;
Object.keys(res).forEach(key => {
if (! res[key]) delete res[key]
if (Array.isArray(res[key])) res[key] = res[key].join('')
})
return res;
}
get(key)
如您所见,我的代码不干净,有更好的方法来实现相同的功能。我真的很努力,我不能做得更好
我的意思是使用 REGEXP
更好 match
非常像这样
在我看来,您可以将对象字段的初始化与对象的创建内联,foreach 不是最好的副作用,尝试制作对象 const
并使用类似的东西过滤和减少:
// the snipped won't work because of the sandbox policy
let key = 'N001DSC29MC22HC22DD04MD09YD21';
function get(key) {
const res = {
matchNumber : key.match(/(?<=N)\d{3}/g),
matchSeconds : key.match(/(?<=DSC)\d{2}/g),
matchMinutes : key.match(/(?<=MC)\d{2}/g),
matchHours : key.match(/(?<=HC)\d{2}/g),
matchDay : key.match(/(?<=DD)\d{2}/g),
matchMonth : key.match(/(?<=MD)\d{2}/g),
matchYear : key.match(/(?<=YD)\d{2}/g),
title : JSON.parse(localStorage.getItem(key)).title,
description : JSON.parse(localStorage.getItem(key)).description,
};
return Object.entries(res)
.filter(([k]) => k)
.reduce((acc, [k,v]) => (acc[k] = v, acc), {})
}
get(key)
但是,您实际上可以避免创建 res
对象并从另一个数据结构开始(Object.entries
将 return 的数据结构)
let key = 'N001DSC29MC22HC22DD04MD09YD21';
function get(key) {
return [
['matchNumber' , key.match(/(?<=N)\d{3}/g)],
['matchSeconds' , key.match(/(?<=DSC)\d{2}/g)],
['matchMinutes' , key.match(/(?<=MC)\d{2}/g)],
['matchHours' , key.match(/(?<=HC)\d{2}/g)],
['matchDay' , key.match(/(?<=DD)\d{2}/g)],
['matchMonth' , key.match(/(?<=MD)\d{2}/g)],
['matchYear' , key.match(/(?<=YD)\d{2}/g)],
['title' , JSON.parse(localStorage.getItem(key)).title],
['description' , JSON.parse(localStorage.getItem(key)).description],
].filter(([k]) => k).reduce((acc, [k,v]) => (acc[k] = v, acc), {})
}
get(key)
使用 Object.fromEntries
创建对象,其中的条目从 Object.entries
过滤和映射看起来更清晰一些。
console.log(get(`N001DSC29MC22HC22DD04MD09YD21`));
function get(key) {
return Object.fromEntries(
Object.entries({
matchNumber: key.match(/(?<=N)\d{3}/g),
matchSeconds: key.match(/(?<=DSC)\d{2}/g),
matchMinutes: key.match(/(?<=MC)\d{2}/g),
matchHours: key.match(/(?<=HC)\d{2}/g),
matchDay: key.match(/(?<=DD)\d{2}/g),
matchMonth: key.match(/(?<=MD)\d{2}/g),
matchYear: key.match(/(?<=YD)\d{2}/g),
// mockup for not working localStorage in sandbox
title: `sometitle`,
description: `somedescription`,
})
// filter only key-value pairs with a value
.filter( ([key, value]) => value )
// map to values with joined Arrays if applic.
.map( ([key, value]) =>
[key, Array.isArray(value) ? value.join('') : value ] )
);
}
备选方案,来自一个 raw string 的标签和正则表达式,使用一个 reducer 创建对象。
const getValuesFromKey = key => ({
...String.raw`
ID::(?<=N)\d{3}
Seconds::(?<=DSC)\d{2}
Minutes::(?<=MC)\d{2}
Hours::(?<=HC)\d{2}
Day::(?<=DD)\d{2}
Month::(?<=MD)\d{2}
NoMatch::(?<=NOTHING)\d{2} // won't match anything
Years::(?<=YD)\d{2} // will find two years `
.split(`\n`)
.reduce( (acc, line) => {
line = line.replace(/\/\/.*$/, ``).trim();
const [label, re] = line && line.split(`::`);
const match = re && key.match(new RegExp(re, `g`));
return match ? {...acc, [[label]]: match.join(` and `)} : acc;
}, {}),
Title: `someTitle`,
Description: `someDescription` });
console.log(getValuesFromKey(`N001DSC29MC22HC22DD04MD09YD21YD45`));
// ^ extra value
或使用named capture groups. See this stackblitz project
嗨, 我有这个代码
let key = N001DSC29MC22HC22DD04MD09YD21
function get(key) {
let res = {};
res.matchNumber = key.match(/(?<=N)\d{3}/g);
res.matchSeconds = key.match(/(?<=DSC)\d{2}/g);
res.matchMinutes = key.match(/(?<=MC)\d{2}/g);
res.matchHours = key.match(/(?<=HC)\d{2}/g);
res.matchDay = key.match(/(?<=DD)\d{2}/g);
res.matchMonth = key.match(/(?<=MD)\d{2}/g);
res.matchYear = key.match(/(?<=YD)\d{2}/g);
res.title = JSON.parse(localStorage.getItem(key)).title;
res.description = JSON.parse(localStorage.getItem(key)).description;
Object.keys(res).forEach(key => {
if (! res[key]) delete res[key]
if (Array.isArray(res[key])) res[key] = res[key].join('')
})
return res;
}
get(key)
如您所见,我的代码不干净,有更好的方法来实现相同的功能。我真的很努力,我不能做得更好
我的意思是使用 REGEXP
更好 match
非常像这样
在我看来,您可以将对象字段的初始化与对象的创建内联,foreach 不是最好的副作用,尝试制作对象 const
并使用类似的东西过滤和减少:
// the snipped won't work because of the sandbox policy
let key = 'N001DSC29MC22HC22DD04MD09YD21';
function get(key) {
const res = {
matchNumber : key.match(/(?<=N)\d{3}/g),
matchSeconds : key.match(/(?<=DSC)\d{2}/g),
matchMinutes : key.match(/(?<=MC)\d{2}/g),
matchHours : key.match(/(?<=HC)\d{2}/g),
matchDay : key.match(/(?<=DD)\d{2}/g),
matchMonth : key.match(/(?<=MD)\d{2}/g),
matchYear : key.match(/(?<=YD)\d{2}/g),
title : JSON.parse(localStorage.getItem(key)).title,
description : JSON.parse(localStorage.getItem(key)).description,
};
return Object.entries(res)
.filter(([k]) => k)
.reduce((acc, [k,v]) => (acc[k] = v, acc), {})
}
get(key)
但是,您实际上可以避免创建 res
对象并从另一个数据结构开始(Object.entries
将 return 的数据结构)
let key = 'N001DSC29MC22HC22DD04MD09YD21';
function get(key) {
return [
['matchNumber' , key.match(/(?<=N)\d{3}/g)],
['matchSeconds' , key.match(/(?<=DSC)\d{2}/g)],
['matchMinutes' , key.match(/(?<=MC)\d{2}/g)],
['matchHours' , key.match(/(?<=HC)\d{2}/g)],
['matchDay' , key.match(/(?<=DD)\d{2}/g)],
['matchMonth' , key.match(/(?<=MD)\d{2}/g)],
['matchYear' , key.match(/(?<=YD)\d{2}/g)],
['title' , JSON.parse(localStorage.getItem(key)).title],
['description' , JSON.parse(localStorage.getItem(key)).description],
].filter(([k]) => k).reduce((acc, [k,v]) => (acc[k] = v, acc), {})
}
get(key)
使用 Object.fromEntries
创建对象,其中的条目从 Object.entries
过滤和映射看起来更清晰一些。
console.log(get(`N001DSC29MC22HC22DD04MD09YD21`));
function get(key) {
return Object.fromEntries(
Object.entries({
matchNumber: key.match(/(?<=N)\d{3}/g),
matchSeconds: key.match(/(?<=DSC)\d{2}/g),
matchMinutes: key.match(/(?<=MC)\d{2}/g),
matchHours: key.match(/(?<=HC)\d{2}/g),
matchDay: key.match(/(?<=DD)\d{2}/g),
matchMonth: key.match(/(?<=MD)\d{2}/g),
matchYear: key.match(/(?<=YD)\d{2}/g),
// mockup for not working localStorage in sandbox
title: `sometitle`,
description: `somedescription`,
})
// filter only key-value pairs with a value
.filter( ([key, value]) => value )
// map to values with joined Arrays if applic.
.map( ([key, value]) =>
[key, Array.isArray(value) ? value.join('') : value ] )
);
}
备选方案,来自一个 raw string 的标签和正则表达式,使用一个 reducer 创建对象。
const getValuesFromKey = key => ({
...String.raw`
ID::(?<=N)\d{3}
Seconds::(?<=DSC)\d{2}
Minutes::(?<=MC)\d{2}
Hours::(?<=HC)\d{2}
Day::(?<=DD)\d{2}
Month::(?<=MD)\d{2}
NoMatch::(?<=NOTHING)\d{2} // won't match anything
Years::(?<=YD)\d{2} // will find two years `
.split(`\n`)
.reduce( (acc, line) => {
line = line.replace(/\/\/.*$/, ``).trim();
const [label, re] = line && line.split(`::`);
const match = re && key.match(new RegExp(re, `g`));
return match ? {...acc, [[label]]: match.join(` and `)} : acc;
}, {}),
Title: `someTitle`,
Description: `someDescription` });
console.log(getValuesFromKey(`N001DSC29MC22HC22DD04MD09YD21YD45`));
// ^ extra value
或使用named capture groups. See this stackblitz project