我最近开始创建一个站点,用户可以在其中输入城市和州或邮政编码,并将该位置的天气结果返回给他们。 我意识到,这样做时,在完善用户输入方面存在一些困难,例如,从用户那里,我需要获取城市和州或邮政编码。 我本可以做这样的事情:
一个简单的搜索,带有三个单独的输入和漂亮的小标签。 但是,从用户体验的角度来看,大多数用户宁愿不必使用3个单独的输入。 因此,我们将其更改为对吗? 我们将创建一个搜索栏,然后让用户将信息输入到一个搜索栏中。 很容易吧? 我们可以从一个搜索栏中获取城市,州和邮政编码。 如果用户按如下格式格式化输入内容,该怎么办:
如果每个用户都完全按照这种格式输入其响应,我们可以简单地将其推送到数组中,然后根据数组中每个元素的位置优化响应。 [0]将是城市,[1]将是州,等等。但是如果响应的格式如下所示,该怎么办:
甚至像这样:
关键是,没有办法保证用户会做什么。 因此,我们需要做的是编写一些逻辑,该逻辑将采用输入中的所有内容,弄清状态和城市,并将两者分开。 由于邮政编码是可选的,因为用户可以执行城市和州或邮政编码,所以我们希望使用邮政编码,因为它更具体。 为此,我们可以简单地编写一条遍历输入的语句,然后说:“好吧,如果您看到一个连续包含5个或更多数字的字符串,请将该字符串隔离开,并去除所有其他内容。”
很简单。 但是,让我们集中讨论如何隔离城市和州(如果用户决定使用)。
这是我的思考过程:由于州和领地只有59种可能性,因此州将更容易被隔离。 如果我们有一个包含所有59个状态的数组,则可以将用户输入与此数组进行匹配,如果匹配,则将其用作我们的状态。 我将在以后对其进行优化以对每个输入使用两个字母的缩写,但稍后我们将进行介绍。
接下来是城市。 这很棘手,因为某些州和城市包含相似或相同的词,例如“纽约,纽约”,“阿拉巴马州阿拉巴马州”,“印第安纳州印第安纳州”等。我们的代码很容易在哪个州和哪个城市,如果我们不小心的话,我们可以轻松地向用户返回他们所期望的东西。
为了避免这种情况,我还将获得一个JSON对象数组,其中包含与每个州相关联的所有城市。 这样,一旦代码确定性地隔离了州,我就可以简单地获取其余数据,并查看它是否与该州的城市阵列中的任何内容匹配。
最后,我需要重新格式化。 我使用的API要求使用以下格式的城市和州:
旧金山和加利福尼亚州,
因此,一旦确定了什么是什么,就可以按照所需的方式格式化数据。 让我们开始吧。 首先是城市/州JSON对象。 该文件将是我将在此处使用的最大文件,因此,一旦页面加载完毕,在用户甚至没有输入任何内容之前,我就想继续将其加载到后台以节省时间。 我在github上找到了我喜欢的JSON对象,该对象具有大部分数据,但是我对其进行了重新格式化,使其更接近我想要的内容。 如果您要下载并遵循以下链接,请使用以下链接: https : //www.dropbox.com/s/uvmjnoql2lo5sqk/weather.json?dl=0
我已将此文件上传到我的mlab数据库,现在将在文档加载后立即使用fetch加载该文件:
fetch(' https://ethans_cute_web_app_api_blah_blah_blah').then(function(response) {
if (response.status != 200) {
window.alert("Oopsie. You must have done something wrong.");
return;
}response.json().then(function(data) {let states = data;
记住变量“状态”,因为我们将不理会它,以后再讲。 我们实际上只是用它来找出城市。
现在让我们弄清楚状态。
首先,我保存一些稍后将要使用的变量。
let input = document.getElementById('input');
let current = document.getElementById('current');接下来,我将开始我的功能,在这里我将开始获取和完善用户输入。
current.onclick = currentAPI;
function currentAPI() {
let inputValue = input.value;
我的想法是,用户可能会输入整个状态,或者输入两个字符的缩写。 因此,我将寻找任何一种可能性。 首先,我将寻找两个字符的缩写。 这是所有59个州和领地缩写的数组。 这将直接在currentAPI函数内部进行:
let stateAbbr = [ "AK",
"AL",
"AR",
"AS",
"AZ",
"CA",
"CO",
"CT",
"DC",
"DE",
"FL",
"GA",
"GU",
"HI",
"IA",
"ID",
"IL",
"IN",
"KS",
"KY",
"LA",
"MA",
"MD",
"ME",
"MI",
"MN",
"MO",
"MS",
"MT",
"NC",
"ND",
"NE",
"NH",
"NJ",
"NM",
"NV",
"NY",
"OH",
"OK",
"OR",
"PA",
"PR",
"RI",
"SC",
"SD",
"TN",
"TX",
"UT",
"VA",
"VI",
"VT",
"WA",
"WI",
"WV",
"WY"]
接下来,我们将检查输入中是否有缩写。 我们将通过遍历输入,将其拆分为单独的文本块来实现。 然后,我们将遍历每一个,看看其中是否有两个字符长。 如果是这样,我们将其与州缩写进行比较。 如果存在匹配项,我们会将其保存为变量。 这是我写这种逻辑的方式:
let possibleState = [];
for (var i = 0; i < text2.length; i++) {
if (text2[i].length == 2) {
possibleState.push(text2[i])
}
}
因此,在这里,如果用户输入了任意两个字符串,则它现在位于我们的“ possibleState”数组中。 如果不是,则我们的数组为空。 我们继续假设其中存在某些内容,将其转换为字符串并针对我们的状态缩写数组进行测试。
let state2 = possibleState.toString();
let uppercaseState = state2.toUpperCase();
let confirmedState = "";
for (var i = 0; i < stateAbbr.length; i++) {
if (stateAbbr[i] == uppercaseState) {
confirmedState = stateAbbr[i];
}
}
好了 我在这里所做的就是采用了possibleState数组,该数组可能会出现状态缩写,并且我已经将数组中的所有内容转换为字符串。 接下来,我将其转换为UpperCase,因为我们用于比较的数组是大写的。 我们要确保我们正在比较苹果与苹果。 然后,我遍历stateAbbr数组,如果数组中的任何状态现在都在变量uppercaseState中与我们可能的状态相匹配,我们将其定义为变量ConfirmedState,因为现在我们已经确认这是最可能的状态是,如果有任何数据。 现在,如果用户未输入任何两个字符串,那么那里可能仍然没有任何内容。 如果那里有东西,那就是我们要使用的东西。 如果没有,我们将要搜索输入状态。 因此,我要做的是继续寻找输入的州名称。 然后,我将创建一个名为“ myState”的变量。 我会说:“如果possibleState数组中有内容,则myState是两个字母的缩写,如果没有,那么它将是输入状态。” 这是我搜索输入状态的方法:
let statesArray = ["alaska",
"alabama",
"arkansas",
"americansamoa",
"arizona",
"california",
"colorado",
"connecticut",
"districtofcolumbia",
"delaware",
"florida",
"georgia",
"guam",
"hawaii",
"iowa",
"idaho",
"illinois",
"indiana",
"kansas",
"kentucky",
"louisiana",
"massachusetts",
"maryland",
"maine",
"michigan",
"minnesota",
"missouri",
"mississippi",
"montana",
"northcarolina",
"northdakota",
"nebraska",
"newhampshire",
"newjersey",
"newmexico",
"nevada",
"newyork",
"ohio",
"oklahoma",
"oregon",
"pennsylvania",
"puertorico",
"rhodeisland",
"southcarolina",
"southdakota",
"tennessee",
"texas",
"utah",
"virginia",
"virginislands",
"vermont",
"washington",
"wisconsin",
"westvirginia",
"wyoming"];
与缩写类似,我得到了所有小写状态的数组,它们之间没有空格。
let text = inputValue.replace(/\W+/g, "");
let inputLowerCase = text.toLowerCase();
let inputUpperCase = text.toUpperCase();
因此,在这里,我已经接受了整个用户输入,去掉了所有空格和字符(例如逗号等),然后将其全部转换为小写字符。 现在我需要比较两者。
let myState = "";
for (var j = 0; j < inputLowerCase.length; j++) {
for (var i = 0; i < statesArray.length; i++) {
if (inputLowerCase.includes(statesArray[i])) {
myState = statesArray[i];
}
}
}
那里。 我正在比较两者。 请记住,我们的输入可能包含许多不同的内容,因此我们只是遍历整个循环,看看状态数组中是否有任何项包含在输入的总字符串中。 因此,如果输入包含来自states数组的任何项目,我们将得到它。 最后,我们需要确定是否要使用缩写(如果用户给了我们一个缩写),还是键入状态(如果用户给了我们缩写)。 这是我要检查的方式:
let stateToUse = "";
if (possibleState.length == 0) {
stateToUse = myState;
} else {
stateToUse = confirmedState;
}
好吧,所以现在,无论哪种方式,我们都有自己的状态。 但是,如果状态不是缩写,我想将其转换为1。 我们知道,无论“ stateToUse”是什么,它要么是缩写,要么是键入状态,小写,没有空格。
let stateMatch = {"alaska": "AK",
"alabama": "AL",
"arkansas": "AR",
"americansamoa": "AS",
"arizona": "AZ",
"california": "CA",
"colorado": "CO",
"connecticut": "CT",
"district of columbia": "DC",
"delaware": "DE",
"florida": "FL",
"georgia": "GA",
"guam": "GU",
"hawaii": "HI",
"iowa": "IA",
"idaho": "ID",
"illinois": "IL",
"indiana": "IN",
"kansas": "KS",
"kentucky": "KY",
"louisiana": "LA",
"massachusetts": "MA",
"maryland": "MD",
"maine": "ME",
"michigan": "MI",
"minnesota": "MN",
"missouri": "MO",
"mississippi": "MS",
"montana": "MT",
"northcarolina": "NC",
"northdakota": "ND",
"nebraska": "NE",
"newhampshire": "NH",
"newjersey": "NJ",
"newmexico": "NM",
"nevada": "NV",
"newyork": "NY",
"ohio": "OH",
"oklahoma": "OK",
"oregon": "OR",
"pennsylvania": "PA",
"puertorico": "PR",
"rhodeisland": "RI",
"southcarolina": "SC",
"southdakota": "SD",
"tennessee": "TN",
"texas": "TX",
"utah": "UT",
"virginia": "VA",
"virginislands": "VI",
"vermont": "VT",
"washington": "WA",
"wisconsin": "WI",
"westvirginia": "WV",
"wyoming": "WY",
};
var re = new RegExp(Object.keys(stateMatch).join("|"), "gi");
keyWord = stateToUse.replace(re, function(matched) {
return stateMatch[matched.toLowerCase()];
});
let state3 = keyWord.toUpperCase();因此,在这里,我将第二种可能性转换为缩写。 此时,无论用户输入的内容是什么,无论大小写还是在字符之间都包含空格,都应如此。 无论如何,在这一点上,我们用两个字母来表示其状态。 完善。 现在开始棘手的部分。 城市。
还记得我们首先加载的JSON数据吗? 数据如下所示:
{ "state":"AL", "city":["ABBEVILLE", "ADAMSVILLE", "etc", "etc", "etc"]
} 每个州都有。 基本上,每个州,每个州的城市都在一个名为“州”的变量中。 这是我将开始遍历的方法:
let myCity = "";
for (var i = 0; i < states.length; i++) {
if (states[i].state == state3) {
for (var k = 0; k < states[i].city.length; k++) {
if(text4.includes(states[i].city[k])) {
myCity = states[i].city[k];
}
}
}
}
我正在使用嵌套的for循环来针对JSON数组中的状态测试我们的缩写状态,以查看是否获得匹配。 获得匹配项后,我们将其保存在变量“ myCity”中。
现在我们需要对其进行格式化。 如果城市是“夏洛特”,我们希望它给我们“夏洛特”首字母大写。 但是,如果我们有“旧金山”呢? 我们希望它返回以下内容:“ San_Francisco”,将每个单词的首字母大写,并用下划线分隔。
let twoCity = myCity.toLowerCase();
let threeCity = [];
let string3 = [];
for (var i = 0; i < twoCity.length; i++) {
if (twoCity[i] == " ") {
let newCity = twoCity.split(" ");
threeCity.push(newCity);
} else if (twoCity.includes(" ") == false && threeCity.includes(twoCity) == false) {
let newCity2 = twoCity;
threeCity.push(newCity2);
}
}
首先,我们将整个字符串转换为小写,然后在空格处将其分割。 这样,我们现在有了一个数组“ threeCity”。 在数组中是我们的城市名称。 我还在for循环的if语句中创建了两种方案。 对于两个单词的城市,说“如果输入字符串包含空格,请执行某些操作”。 然后,第二种情况是我们正在处理一个单词的城市,所以我说,“如果输入内容不包含空格。” 如果城市名称超过一个单词,则每个单词都是其自己的数组项。
let string4 = [];
for (var i = 0; i < threeCity.length; i++) {
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
}
if (threeCity.length <= 1) {
let cityString = threeCity.toString();
let newWord = cityString.capitalize();
string4.push(newWord);
} else if (threeCity[0].length > 1) {
for (var i = 0; i < threeCity[0].length; i++) {
let newWord2 = threeCity[0][i].capitalize();
string4.push(newWord2);
}
}
}
let string5 = string4.toString();
let string6 = string5.replace(",", "_");
在这里,我采用threeCity数组,并通过一个函数将其运行,该函数将每个数组项的首字母大写。 现在,如果我们的城市是一个单词,两个单词或5个单词或其他,则每个单词都大写。
然后,我将数组转换为字符串,这意味着我现在每个单词都大写,并用逗号分隔。 所以我只是简单地使用字符串替换方法,用下划线替换逗号。
- 这可能有点复杂。 而且我敢肯定,有一种更简单的方法可以做到这一点。 但是它可以正常运行,并且运行很快。 太好了,因为我可以确定,无论用户输入了什么内容,或者用户输入的格式设置有多么糟糕,我都会得到州和城市的信息。 (只要我的城市阵列是最新的)。
现在,我可以使用该城市和州来从天气API中获取数据,这还是我的初衷。 但是我为最终用户简化了流程,使最终用户现在可以在一个简单的搜索栏中输入所有内容。
让我知道您是否有任何反馈意见。 谢谢!
From: https://hackernoon.com/creating-a-better-user-experience-with-regular-expressions-f2bbf6e42c87