【问题标题】:How do I access a variable, created outside of an IF/ELSE scope, update it in the IF statement, and access that update in the ELSE statement?如何访问在 IF/ELSE 范围之外创建的变量、在 IF 语句中更新它并在 ELSE 语句中访问该更新?
【发布时间】:2020-03-30 20:18:09
【问题描述】:

抱歉,我不知道该如何表达我的问题,因此我很难找到任何相关的解决方案。

项目

我正在创建一个脚本,用于从 Excel 文件中清除成批的原始文本...

...将每个“细胞”收集到一个数组中,并将每个“人”推入一个新数组,同时将他们各自的信息位附加到每个人。文本本身包含名字、姓氏和城市等内容。有些人在新线路上有多个城市......

*所有信息都是随机生成的,任何现实生活中的比较纯属巧合

问题

我能够清理文本并将每一行的内容转储到一个数组中,没有任何问题,但是当我尝试将只有一个城市的“行”推送到最近的“完整人”时,问题就来了.例如:

John Doe 曾住在阿拉斯加州安克雷奇;纽约,纽约;和爱荷华州得梅因。

New York, NY 和 Des Moines, IA 各自以各自的行结束,每个城市都是数组中的唯一项目。

当我将一个城市推入新数组时,我得到:

Uncaught TypeError: Cannot read property 'city' of undefined

守则

这是我正在使用的代码。具体来说,我的问题在于mergeSort(a) 函数:

function sanitize(rawData) { // Accessed from event handler on line 70
  // Split the raw data into "lines"
  const splitByLine = rawData.split("\n");

  // Split each line into an array by "tabs"
  const splitByTab = splitByLine.map(line => {
    return line.split("\t");
  });

  // Trim each array cell and remove any empty cells
  const cleaned = splitByTab.map(function(item) {
    const scrubbed = item.map(chunk => {
      return chunk.trim();
    });

    const trimmed = scrubbed.filter(chunk => {
      return chunk !== "";
    });

    return trimmed;
  });

  // Remove any empty arrays
  const droppedEmpties = cleaned.filter(arrayItem => {
    return arrayItem.length > 0;
  });

  mergeSort(droppedEmpties); // Line 32
}

// Sort cities lived in for each person
function mergeSort(a) {
  console.log(a);

  function Person(firstName, lastName, gender, city, birthday) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.gender = gender;
    this.city = [city];
    this.birthday = birthday;
  }

  const people = [];

  let toggleID = 0;

  a.forEach(person => {
    // If the entry is likely to be a person...
    if (person.length > 1) {
      // Set the ID for the last known person
      toggleID = a.indexOf(person);

      let newPerson = new Person(
        person[0], // firstName
        person[1], // lastName
        person[2], // gender
        person[3], // city
        person[4] // birthday
      );

      people.push(newPerson);
      console.log(people[toggleID]);
    } else { // ...Else assume it's a city and push to the previous person.
      people[toggleID].city.push(person[0]); // THROWS ERROR: Cannot read property of 'city' of undefined
    }
  });
}

// Get form submission
document.getElementById("my-form").addEventListener("submit", function(e) {
  e.preventDefault();
  const textarea = document.getElementById("my-textarea");
  const rawData = textarea.value;
  sanitize(rawData); // Line 1
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <form id="my-form">
    <button>Submit</button>
    <textarea id="my-textarea" cols="150" rows="15">
Cynthia	Hogsett	Female	Grand Rapids, MI	12/6/1983
Jacqueline	Crosborne	Female	Syracuse, NY	3/19/1984
Ricky	Johnson	Male	Tioga, ND	4/6/1972
Jimmy	Jessup	Male	Ames, IA	10/27/1993
            Williston, ND	
            Grand Forks, ND	
Andrew	Manchez	Male	El Paso, TX	3/1/2001
Sarah	Smith	Female	Seattle, WA	7/19/1981
Esteban	Faccin	Male	Gilbert, AZ	1/30/1973
            Spokane, WA	
            Minot, ND	
            James Town, CO	
                </textarea>
  </form>
  <script src="main.js"></script>
</body>

</html>

我的猜测是,尽管我在 IF/ELSE 范围之外定义了 let toggleID,但我无法改变 IF statement 中的值并从 ELSE statement 中访问更新后的值。

提前感谢您的任何见解!

【问题讨论】:

    标签: javascript arrays object if-statement variables


    【解决方案1】:

    好吧,if 块和 else 块不会同时执行,因此您需要希望 toggleID 已在某些之前的迭代中设置环形。这很难保证。但实际上这不是您的问题,toggleID 已按您的预期设置。问题在于,当其中一个元素不是被推送到people 的人时,在随后的运行中,下一个人确实将pushed 获取到下一个空闲索引。不要toggleID。您应该看到console.log(people[toggleID]);(在if 块内)记录undefined,甚至它抛出异常之前。

    a.indexOf(person)(或者更好的是,forEach 回调的第二个参数)将引用原始 a 数组中看到的最后一个索引,而不是与获取前一个人相关的 people 数组。使用它来索引people 有时会得出错误(否)的结果 - 因为您不会每次都为a 中的每个元素创建一个新人。

    相反,您可以

    • 根本不存储toggleID,而是每次都使用people[people.length-1]动态查找数组中的最后一个元素。
    • 不存储索引,只存储您创建的最后一个newPerson 对象。
    • 获取正确的索引,例如通过在people.push(…) 之前执行toggleID = people.length,或通过执行toggleID = people.push(…) - 1;

    【讨论】:

    • 你是对的。如此执着于看似如此明显的事情,我感到有点傻。我删除了 [toggleID] 位并按照您的建议开始向 people[people.length-1] 推送,这一切都到位了。感谢您抽出宝贵的时间回复,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 2021-12-27
    • 2020-10-29
    • 2020-07-06
    • 2016-10-13
    • 2019-06-02
    相关资源
    最近更新 更多