JavaScript 学校练习 - 提示和数组

JavaScript School Exercise - Prompt & Array

我需要解决这个学校练习,但我不知道如何解决。正文如下:

我需要制作一个程序,通过 prompt() 对话框从用户那里获取信息。用户需要输入的信息是他的姓名和性别(例如 Marc,m)。基于这些信息,程序需要在 alert() 对话框中写入(已经给出的)列表中的形容词,这些形容词的开头字母与姓名中的字母相同。

例如:用户姓名为Marc,性别为男。程序需要使用男性列表中的形容词(有两个形容词列表,男性和女性),并在警告对话框中这样写:

疯狂

准确

推理

计算

如果你竖读他们的第一个字母,他们说的是 MARC。

我对字母表中的所有字母都有形容词,包括男性和女性。 请记住,变量名和形容词是我的母语(塞尔维亚语),但这应该不是问题,你会明白我的意思,我会在评论中解释代码。

var pridevi = {
  m: ["atraktivan", "blesav", "ciničan", "čudan", "ćopav", "duhovit", "džangrizav", "đavolast", "elokventan", "fantastičan", "grozan", "halapljiv", "imućan", "jak", "katastrofalan", "lep", "ljubazan", "mudar", "naivan", "njanjav", "otporan", "posesivan", "razigran", "smešan", "šaljiv", "tolerantan", "uobražen", "veseo", "zabrinut", "žut"],
  z: ["atraktivna", "blesava", "cinična", "čudna", "ćopava", "duhovita", "džangrizava", "đavolasta", "elokventna", "fantastična", "grozna", "halapljiva", "imućna", "jaka", "katastrofalna", "lepa", "ljubazna", "mudra",  "naivna", "njanjava", "otporna", "posesivna", "razigrana", "smešna", "šaljiva", "tolerantna", "uobražena", "vesela", "zabrinuta", "žuta"],
} // I stored adjectives in object where property m: stands for male and property f: stands for female adjectives

var unos = prompt("Upišite ime i pol. Npr. Mirko, m"); // prompt format

var ime = unos.toLowerCase().split(", ").shift(); // in this variable I stored name
var pol = unos.toLowerCase().split(", ").pop(); // in this variable I stored sex

// console.log(ime + " " + pol) > mirko m

if (unos === null) {
  alert("Korisnik je odustao."); // if user clicks cancel, this message shows in alert dialog
}
else if (unos === undefined && ime < 0 && pol < 0) {
  alert("Nisu uneseni ispravni podaci."); // if user doesn't write the data in correct form, this message shows in alert dialog
}
else {
  var odgovor = pridevi[pol].find(opis => ime[0] === opis[0]); // here's the main thing that doesn't work as it should. it only shows the adjective of the first letter of the name, but not all of them
  alert(odgovor);
}

这个答案依赖于模式匹配,它相当脆弱,因为如果有人不遵循定义的格式,它将无法正常工作。一些注意事项:

  • 将形容词组移动到一个持有对象中,因为访问动态属性相当简单并且需要更少的 if/else 链接才能到达正确的数组组。
  • 定义了一些实用的箭头函数。如果这些不熟悉,请随意使用标准函数尝试它们,如下所示:
    • function notEmpty(val) { return (val !== undefined && val !== null && val.length > 0); }
  • 使用 Array.prototype.map 使用回调重新格式化结果数组
  • 使用数组解构语法,您可以在获取映射结果后通过定义这些变量来替换它 (const name = mappedArray[0])
  • 在 JS 中,你不需要在访问它的索引之前拆分一个字符串,所以 'string'[0] 会给你 's',这在 Array.prototype.find 回调函数中很有用

// adjective group
const adjectives = {
  f: ["accurate", "bodybuilder", "calculative", "decisive" ],
  m: ["abstract", "beautiful", "capable", "delightful" ],
}

// utility function to check that a value exists and isn't empty
const notEmpty = val => (val !== undefined && val !== null && val.length > 0);

// prompt response holder (define a format)
const question = prompt("Write your given name and sex (format: Marc, m.)");

// function to format each entry in the response 
// /\W/g is a regex for stripping non alphanumeric 
const formatEntries = val => val.replace(/\W/g, '').toLowerCase();

// use format to split and handle your response
const [name, adjectiveGroup] = question.split(", ", 2)
  .map(formatEntries)

// if both variables are set then try and find matching adjective
if (notEmpty(name) && notEmpty(adjectiveGroup)) {
    const answer = adjectives[adjectiveGroup].find(adj => name[0] === adj[0])  
  
    console.log(answer);
}

经过几天的努力,我终于解决了这个问题。我不得不说 @D Lowther 帮了我几行,例如将男性和女性形容词存储在一个对象而不是两个数组中,并以这种方式将条目从提示中拆分出来 var [name, adjectiveGroup] = question.split(", ", 2)。这些真的很有用。

您可以点击运行立即查看程序。

// in this object I stored all the adjectives, both male and female, because on my language they are various depending on the sex
var pridevi = {
  m: ["атрактиван", "блесав", "циничан", "чудан", "ћопав", "духовит", "џангризав", "ђаволаст", "елоквентан", "фантастичан", "грозан", "халапљив", "имућан", "јак", "катастрофалан", "леп", "љубазан", "мудар", "наиван", "њањав", "отпоран", "посесиван", "разигран", "смешан", "шаљив", "толерантан", "уображен", "весео", "забринут", "жут"],
  z: ["атрактивна", "блесава", "цинична", "чудна", "ћопава", "духовита", "џангризава", "ђаволаста", "елоквентна", "фантастична", "грозна", "халапљива", "имућна", "јака", "катастрофална", "лепа", "љубазна", "мудра",  "наивна", "њањава", "отпорна", "посесивна", "разиграна", "смешна", "шаљива", "толерантна", "уображена", "весела", "забринута", "жута"]
}

// prompt form
var unos = prompt("Упишите име и пол. Нпр. Мирко, м.");

// here I separated the prompt entry into array of two values: name and sex
var [ime, pol] = unos.toLowerCase().split(", ", 2);

// here I stored my native language because that language is required in prompt entry
var cirilica = /[\u0400-\u04FF]/;

// here I later stored the final array
var ispis = [];

// I made a function that converts the first letter of all values in array to uppercase
function velikoSlovo(a) {
  for (var i = 0; i < a.length; i++) {
    a[i] = a[i][0].toUpperCase() + a[i].substr(1);
  }
  return a.join("\n");
}

// if user clicks Cancel, the notification in alert window shows up
if (unos === null) {
  alert("Корисник је одустао.");
}

// here I tested various things: if the prompt entry is empty || if there's either name or sex missing || if it's not on my native language - the notification in alert window shows up
else if (unos.trim() === "" || (unos.split(", ").length < 2) || cirilica.test(unos) === false) {
  alert("Нису унесени исправни подаци.");
}

// if there are other values for sex instead of "m/f" (male/female), the notification in alert window shows up
else if ((unos.split(", ", 2)[1] !== "м") && (unos.split(", ", 2)[1] !== "ж")) {
  alert("Нису унесени исправни подаци.");  
}

// if prompt entry is correct (eg. Marc, m), I tested if the sex is male "м" or female "ж". Based on that, I used loop to compare the first letter of all the adjectives in array with all the letters of the name and then stored all the adjectives that match in the final array that I initialized before. Finally, I showed the final result in alert window and used the function to capitalize each word in string
else {
  if (pol === "м") {
    for (var i = 0; i < ime.length; i++) {
      for (var e = 0; e < pridevi.m.length; e++) {
        if (ime.charAt(i) === pridevi.m[e].charAt(0)) {
          ispis.push(pridevi.m[e]);
        }
      }
    }
    alert(velikoSlovo(ispis));
  }  
  
  else if (pol === "ж") {
    for (var i = 0; i < ime.length; i++) {
      for (var e = 0; e < pridevi.z.length; e++) {
        if (ime.charAt(i) === pridevi.z[e].charAt(0)) {
          ispis.push(pridevi.z[e]);
        }
      }
    }
    alert(velikoSlovo(ispis));  
  }     
}