有比写火柴更好的方法吗



HI,我有这个代码

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)

正如您所看到的,我的代码并不干净,有任何更好的方法可以实现相同的功能。我真的很努力,但我不能做得更好

我的意思是,使用REGEXPmatch会更好,就像这个一样

在我看来,您可以将对象字段的初始化与对象的创建内联,而foreach并不是最好的副作用,请尝试使对象const并使用类似filter和reduce:的东西

// 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将返回的数据结构)开始

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 ] )
);
}

或者,从一个原始字符串中标记和正则表达式,使用一个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

或者使用命名的捕获组。请参阅此堆叠litz项目

最新更新