如何从复杂数据中格式化可读字符串

How to format a readable string from complex data

我有一个函数接收一个由 4 个数组组成的对象,第一个数组包含一个缺少文件 A 的客户列表,第二个数组包含一个需要更新文件的客户列表- A,第三个是缺少文件-B的客户列表,第四个是需要更新文件-B的客户列表。

我有接收对象并检查所有 4 个数组然后生成这样的电子邮件的功能“这是一封电子邮件,通知您客户 A 和 B 缺少文件 A,客户 C 和 D 需要要更新文件 A,客户 A 和 B 缺少文件 B,客户 F 和 E 需要更新文件 B

我想生成此电子邮件的方式是通过 if 语句,但实际上有 16 种不同的条件我必须为其自定义消息。

我觉得写 15 个 else 语句不是办法。

我在下面列出了所有可能的组合,0表示数组中没有客户,1表示数组中有客户。

我想我的问题是有人知道更有效的方法吗?通常,您如何处理可能有 16 个不同条件的复杂 if 语句?

生成您问题中的电子邮件只需要一个if,而不是您认为的地方。您的电子邮件将如下所示:

function generateMessage(data) {
  // Assuming data looks like this:
  // type Data = {
  //   aMissing: string[];
  //   aUpdate: string[];
  //   bMissing: string[];
  //   bUpdate: string[];
  // };

  function joinListWithAnd(list) {
    if (list && list.length > 1) {
      const last = list.pop();
      return `${list.join(", ")} and ${last}`;
    }
    return list && list.length ? list[0] : null
  }

  const pieces = {
    aMissing: " are missing file-A",
    aUpdate: " need to update file-A",
    bMissing: " are missing file-B",
    bUpdate: " need to update file-B",
  };

  const statusMessages = [];
  for (const [key, value] of Object.entries(data)) {
    statusMessages.push(`customers ${joinListWithAnd(data.value)} ${pieces[key]}`);
  }
  return `This is an email to inform you that ${joinListWithAnd(statusMessages)}.`
}

console.log(generateMessage({aMissing: ["A", "B"], bMissing: ["C"], bUpdate: ["A", "B", "C"]}))

您要发送的电子邮件的结构与您要发送的数据的结构相同,因此无需条件检查 运行 构建批量结构。唯一有条件的部分是弄清楚如何格式化列表,因为英语指定单词 and 在长度大于 1 的列表中出现倒数第二个。

您可以 zip 数组并重新创建一个对象 fromEntries(),这样您就可以有效地检查哪些人丢失了文件或哪些文件需要更新。然后,您可以通过创建句子并将它们 joining 放在一起来形成邮件字符串。

// assumed object
const data = {
  aMissing: [0, 1, 0, 1, 0, 1],
  aUpdate: [1, 1, 0, 0, 0, 1],
  bMissing: [0, 1, 1, 1, 0, 1],
  bUpdate: [0, 1, 0, 0, 0, 0]
}

const getFilesPerPerson = (data) => {
  const values = Object.values(data); // get values
  const keys = Object.keys(data)

  // merge (zip) arrays into entries [personx: [x, x, x, x]]
  const mergedValues = values[0].map((_, i) => {
    return [
      `Person${i+1}`,
      values.map((val) => val[i]).map((v, j) => v && keys[j]).filter(x => x)
    ];
  });
  return Object.fromEntries(mergedValues); // create object from entries
}

const writeMail = (people) => {
  // create sentences
  const sentences = Object.entries(people).map(([k, v]) => {
    return `${k} has${v.map((val) => ` ${val}`)}.`;
  });
  return sentences.join(" "); // join to mail
}

const people = getFilesPerPerson(data);
const mail = writeMail(people);
console.log(mail);