Im trying to create a save to pdf method using the simplePDF framework on Github. I have several arrays and have tried to use a for in loop. Its my first go at this, but I do not understand why I am getting fatal error: Index out of range. Here is my code.
我试图在Github上使用simplePDF框架创建一个保存到pdf方法。我有几个数组,并尝试使用for循环。这是我的第一次,但我不明白为什么我会致命的错误:索引超出范围。这是我的代码。
let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)
let count = Globals.datesArray.count
var sum = 0
for index in 0...count {
pdf.addText(Globals.datesArray[index])
pdf.addText(Globals.titleArray[index])
pdf.addText(Globals.descriptionArray[index])
sum += index
}
let pdfData = pdf.generatePDFdata()
Any help is much appreciated. Thanks!
任何帮助深表感谢。谢谢!
3 个解决方案
#1
4
Both answers are correct, but neither are ideal.
两个答案都是正确的,但都不是理想的。
This would work:
这可行:
for index in 0..<count {
However, it's much better to use:
但是,使用它会好得多:
for index in Globals.datesArray.indicies
This way the range is created for you, and removes the potential for a typo (...
instead of ..<
)
这样就为你创建了范围,并消除了错字的可能性(...而不是.. <)
On a side note:
What concerns me is your use of 3 arrays to store related data. Wikipedia has a section on the pros and cons of parallel arrays. They really have no place in modern, high-level programming. They're cumbersome to work with, and very fragile. For example, if you add an element to the middle of datesArray
and titleArray
, but forget to add a description in descriptionArray
, all of a sudden, you have mismatching between your dates/titles and descriptions.
我关心的是您使用3个数组来存储相关数据。*有一节关于并行数组的优缺点。他们在现代高级编程中确实没有地位。他们工作繁琐,而且非常脆弱。例如,如果将一个元素添加到datesArray和titleArray的中间,但忘记在descriptionArray中添加描述,那么突然之间,您的日期/标题和描述之间会有不匹配。
You should try using a class
or struct
. For example, you might want a struct declaration like this:
您应该尝试使用类或结构。例如,您可能需要这样的结构声明:
struct Thing { //TODO: give me a name!
let date: Date
let title: String
let description: String
}
This lets you change a messy parallel structure like this:
这可以让你改变一个凌乱的并行结构,如下所示:
let datesArray = [date0, date1, date2]
let titlesArray = ["title0", "title1", "title2"]
let descriptionsArray = ["Description 0", "Description 1", "Description 2"]
Into one like this:
进入这样一个:
let things = [
Thing(
date: date0,
title: "title0"
description: "Description 0"
),
Thing(
date: date1,
title: "title1"
description: "Description 1"
),
Thing(
date: date2,
title: "title2"
description: "Description 2"
),
]
With this second declaration, all the information pertaining to a single Thing
is stored cohesively. It lets you much more easily make additions/edits. No more counting elements to make sure they're lined up!
通过这个第二个声明,所有与单个事物有关的信息都是紧密地存储起来的。它可以让您更轻松地进行添加/编辑。没有更多计数元素,以确保他们排队!
With such a struct in place, your code can be written like this:
有了这样的结构,您的代码可以这样编写:
let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)
var sum = 0
for (index, thing) in things.enumerated() {
pdf.addText(thing.date)
pdf.addText(thing.title)
pdf.addText(thing.description)
sum += index
}
let pdfData = pdf.generatePDFdata()
That snippet uses enumerated()
, which lets you iterate over elements and their index. This way, we don't have to subscript our array in the loop body.
该代码段使用enumerated(),它允许您迭代元素及其索引。这样,我们就不必在循环体中下标我们的数组。
However, the sum
in this case will always be the sum of 0, 1, ... , count
. This is equal to just (count * (count + 1)) / 2
, so we can simplify the code further:
但是,在这种情况下,总和将始终是0,1,...,count的总和。这等于just(count *(count + 1))/ 2,因此我们可以进一步简化代码:
let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)
for (index, thing) in things.enumerated() {
pdf.addText(thing.date)
pdf.addText(thing.title)
pdf.addText(thing.description)
}
let pdfData = pdf.generatePDFdata()
let sum = (count * (count + 1)) / 2
Now since we're not using index
in the for
loop body anymore, we can use regular iteration, without enumerated()
:
现在因为我们不再在for循环体中使用索引,所以我们可以使用常规迭代,而不使用enumerated():
let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)
for index in things {
pdf.addText(thing.date)
pdf.addText(thing.title)
pdf.addText(thing.description)
}
let pdfData = pdf.generatePDFdata()
let sum = (count * (count + 1)) / 2
#2
2
Alternatively to David's answer:
大卫回答的替代方案:
for index in 0...count {
could be
for index in 0..<count {
This will loop up until but not including count.
这将循环直到但不包括计数。
#3
1
I think it should be let count = Globals.datesArray.count - 1
. If Globals.count == 3, then index are [0,1,2], [3] would be out of range.
我认为应该让count = Globals.datesArray.count - 1.如果Globals.count == 3,则index为[0,1,2],[3]将超出范围。
#1
4
Both answers are correct, but neither are ideal.
两个答案都是正确的,但都不是理想的。
This would work:
这可行:
for index in 0..<count {
However, it's much better to use:
但是,使用它会好得多:
for index in Globals.datesArray.indicies
This way the range is created for you, and removes the potential for a typo (...
instead of ..<
)
这样就为你创建了范围,并消除了错字的可能性(...而不是.. <)
On a side note:
What concerns me is your use of 3 arrays to store related data. Wikipedia has a section on the pros and cons of parallel arrays. They really have no place in modern, high-level programming. They're cumbersome to work with, and very fragile. For example, if you add an element to the middle of datesArray
and titleArray
, but forget to add a description in descriptionArray
, all of a sudden, you have mismatching between your dates/titles and descriptions.
我关心的是您使用3个数组来存储相关数据。*有一节关于并行数组的优缺点。他们在现代高级编程中确实没有地位。他们工作繁琐,而且非常脆弱。例如,如果将一个元素添加到datesArray和titleArray的中间,但忘记在descriptionArray中添加描述,那么突然之间,您的日期/标题和描述之间会有不匹配。
You should try using a class
or struct
. For example, you might want a struct declaration like this:
您应该尝试使用类或结构。例如,您可能需要这样的结构声明:
struct Thing { //TODO: give me a name!
let date: Date
let title: String
let description: String
}
This lets you change a messy parallel structure like this:
这可以让你改变一个凌乱的并行结构,如下所示:
let datesArray = [date0, date1, date2]
let titlesArray = ["title0", "title1", "title2"]
let descriptionsArray = ["Description 0", "Description 1", "Description 2"]
Into one like this:
进入这样一个:
let things = [
Thing(
date: date0,
title: "title0"
description: "Description 0"
),
Thing(
date: date1,
title: "title1"
description: "Description 1"
),
Thing(
date: date2,
title: "title2"
description: "Description 2"
),
]
With this second declaration, all the information pertaining to a single Thing
is stored cohesively. It lets you much more easily make additions/edits. No more counting elements to make sure they're lined up!
通过这个第二个声明,所有与单个事物有关的信息都是紧密地存储起来的。它可以让您更轻松地进行添加/编辑。没有更多计数元素,以确保他们排队!
With such a struct in place, your code can be written like this:
有了这样的结构,您的代码可以这样编写:
let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)
var sum = 0
for (index, thing) in things.enumerated() {
pdf.addText(thing.date)
pdf.addText(thing.title)
pdf.addText(thing.description)
sum += index
}
let pdfData = pdf.generatePDFdata()
That snippet uses enumerated()
, which lets you iterate over elements and their index. This way, we don't have to subscript our array in the loop body.
该代码段使用enumerated(),它允许您迭代元素及其索引。这样,我们就不必在循环体中下标我们的数组。
However, the sum
in this case will always be the sum of 0, 1, ... , count
. This is equal to just (count * (count + 1)) / 2
, so we can simplify the code further:
但是,在这种情况下,总和将始终是0,1,...,count的总和。这等于just(count *(count + 1))/ 2,因此我们可以进一步简化代码:
let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)
for (index, thing) in things.enumerated() {
pdf.addText(thing.date)
pdf.addText(thing.title)
pdf.addText(thing.description)
}
let pdfData = pdf.generatePDFdata()
let sum = (count * (count + 1)) / 2
Now since we're not using index
in the for
loop body anymore, we can use regular iteration, without enumerated()
:
现在因为我们不再在for循环体中使用索引,所以我们可以使用常规迭代,而不使用enumerated():
let A4paperSize = CGSize(width: 595, height: 842)
let pdf = SimplePDF(pageSize: A4paperSize)
pdf.setContentAlignment(.center)
for index in things {
pdf.addText(thing.date)
pdf.addText(thing.title)
pdf.addText(thing.description)
}
let pdfData = pdf.generatePDFdata()
let sum = (count * (count + 1)) / 2
#2
2
Alternatively to David's answer:
大卫回答的替代方案:
for index in 0...count {
could be
for index in 0..<count {
This will loop up until but not including count.
这将循环直到但不包括计数。
#3
1
I think it should be let count = Globals.datesArray.count - 1
. If Globals.count == 3, then index are [0,1,2], [3] would be out of range.
我认为应该让count = Globals.datesArray.count - 1.如果Globals.count == 3,则index为[0,1,2],[3]将超出范围。