对不起,我不确定该如何用其他方式表达我的问题,因此,很难找到任何相关的解决方案。
项目
我正在创建一个脚本,用于清除Excel文件中的大量原始文本...
...将每个“单元”聚集到一个数组中,并将每个“人”推入一个新的数组中,同时将每个人的相应信息附加到每个人上。文本本身包含诸如名字,姓氏和城市之类的东西。有些人在新线路上有多个城市...
* 所有信息都是随机生成的,任何现实生活中的比较纯属巧合
问题
我可以清理文本并将每行的内容转储到数组中,而不会出现任何问题,但是当我尝试将只有一个城市的“行”推送到最近的“完整人员”时,问题就来了。例如:
约翰·多伊(John Doe)生活在阿克拉的安克雷奇(Anchorage);纽约,纽约;和爱荷华州得梅因。
纽约州纽约市和爱荷华州得梅因市各自以各自的路线结尾,每个城市是阵列中的唯一项目。
当我将一个城市推入新阵列时,我得到:
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>
我的猜测是,尽管我在toggleID
范围之外定义了IF/ELSE
,但是我无法对IF statement
中的值进行更改,也无法从内部访问更新后的值ELSE statement
。
在此先感谢您的见解!
答案 0 :(得分: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
对象。toggleID = people.length
之前进行people.push(…)
或通过进行toggleID = people.push(…) - 1;