How to print index number on tableview cell? - swift

I want to print the number of the tableview cell based on the number of tableview cells that are there so if there are 15 cells. The first cell should be 1 and the 15th should state 15. I want this printed before a fetch that is already being printed. I posted a picture of what I am looking for below.
cell.textLabel?.text = [" Course: ",attr1," : ", attr2].flatMap { $0 }.reduce("", +)

You can try:
let text = [" Course: ",attr1," : ", attr2].flatMap { $0 }.reduce("", +)
cell.textLabel?.text = "\(indexPath.row+1) \(text)"
Hope this helps.

Related

Why is only my last object added to the array?

So, I have a class Stand which has an array of type Bike.
I create a few object of class Stand and then I want to add a few bikes to the array of type Bike. Every stand should have a different number of bikes in this list.
Then I have to show the list of stands on a mapView, where the the number of bikes for every stand is shown.
My Problem is that when I add for example, I have 3 stands, only the bikes for the last stand are shown in number of bikes per stand.
So, if stand 1 has 2 bikes, stand 2 has 1 bike and stand bike has 3 bikes - all stands will show that they have 3 bikes.
In other words, for some reason only the last object is added to the list. How can I fix that?
It is pretty much hardcoded for now.
Here is my code:
var stands = [Stand] ()
var stand101 = Stand(id:101, nrOfSpots:15,latitude:51.4516,longtitude:5.4697)
var stand102 = Stand(id:102, nrOfSpots:15,latitude:51.4616,longtitude:5.4997)
var stand103 = Stand(id:103, nrOfSpots:15,latitude:51.4345,longtitude:5.4397)
stand101.addBikeToStand(bike:Bike(id:1,name:"BikeToHeaven",latitude:51.4416,longtitude:5.4697,available:true))
stand101.addBikeToStand(bike:Bike(id:2,name:"BikeToHell",latitude:51.4616,longtitude:5.4997,available:true))
stands.append(stand101)
stand102.addBikeToStand(bike:Bike(id:3,name:"BikeToBulgaria",latitude:51.4345,longtitude:5.4397,available:true))
stands.append(stand102)
stand103.addBikeToStand(bike:Bike(id:4,name:"Sparta",latitude:51.4316,longtitude:5.4697,available:false))
stand103.addBikeToStand(bike:Bike(id:5,name:"Athene",latitude:51.4116,longtitude:5.4997,available:true))
stands.append(stand103)
EDIT
// How bikes are shown
for s in fietshare.stands {
lbAvailable.text = "Available Bikes: " + String(s.bikes.count)
nrOfAvailable.text = String(b.distance) + "M"
}
In your loop
// How bikes are shown
for s in fietshare.stands {
lbAvailable.text = "Available Bikes: " + String(s.bikes.count)
nrOfAvailable.text = String(b.distance) + "M"
}
you are iterating through stands array and showing the number of available bikes, the problem here is your label will always show the number of bikes in the last object.
To overcome this problem you have to make a number of labels equal to number of stands
fietshare.stands.forEach { s in
let lbAvailable = UILabel()
let nrOfAvailable = UILabel()
lbAvailable.text = "Available Bikes: " + String(s.bikes.count)
nrOfAvailable.text = String(b.distance) + "M"
}

How do I add numbers to each tableview row beginning from 1

I have created a TableView with a Prototype Cell with a lot of content in it, multiple labels, 2 pictures and a view which is colored if the row is selected.
What I want to do now, is I want to add a number for each of the rows created so the user can see how many rows there are. I can't use the ID I get from the Database since it is a random mix of characters.
I added an Int variable 'participantID' which starts from one and increments by one with every cell created and writes the value in a label within the prototype cell.
This does exactly what I want, with just one issue: Every time i scroll in the table the ID is incremented. I know that's because of the reuse of the cells however I couldn't find a way to fix this issue.
This is how it looks (particID):
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tbcCourseParticipant", for: indexPath) as! participantCell
let partic = participants[indexPath.row]
cell.lblId?.text = String(particID)
cell.lblName?.text = partic.name
cell.lblFirstName?.text = partic.firstName
cell.lblBirthDate?.text = partic.birthDate
cell.lblPhoneNr?.text = partic.phoneNr
cell.lblPrice?.text = String(partic.payed) + "€"
particID += 1
return(cell)
}
The total number of rows is participants.count. The number of this row is indexPath.row+1 (I add 1 because the user will not expect to start counting at zero the way a programmer would do).
So I would say:
cell.lblId?.text = String(indexPath.row+1)
Or maybe:
cell.lblId?.text = String(indexPath.row+1) + " of " + String(participants.count)

Passing hashset itself as parameter for reduce in swift

Given a hashset h = [1,2,3,4,5] for example, the purpose is to count the number of unique element i such that h.contains(i+1).
I can write down swift code using reduce() as
h.reduce(0,{h.contains($1+1) ? $0 + 1 : $0})
But what if h is an array containing duplicates instead of a hashset? I first need to convert it into hashset and then using the above expression:
Set(h).reduce(0,{Set(h).contains($1+1) ? $0 + 1 : $0})
But in this way we calculated Set(h).count + 1 times of Set(h) as pointed out by #carpsen90, is there any way to write the code like
Set(h).reduce(0,{self.contains($1+1) ? $0 + 1 : $0})
without using a temporary variable to store Set(h)?
Every time you call Set(h) a new set is calculated, so in your example Set(h).reduce(0,{Set(h).contains($1+1) ? $0 + 1 : $0}) , Set(h) will be calculated h.count + 1 times. Having a variable let set = Set(h) is the way to go here :
let set = Set(h)
let result = set.reduce(0) {set.contains($1+1) ? $0 + 1 : $0}
He is an alternative way of getting the desired result :
Let's create a dictionary that indicates wether a number has appeared in h:
var dict = [Int: Bool].init(minimumCapacity: h.count)
for x in h {
if dict[x] == nil {
dict[x] = true
}
}
And then, for each h element, check that its successor appears in the dictionary :
var count = 0
for entry in dict {
if dict[entry.key + 1] == true {
count += 1
}
}
And you could check the result :
print(count) //4
The problem here is that your array might contain duplicates and to filter the duplicates the easiest way is to convert it into the Set. And the correct way to do that is to save the set in a new variable hence it is unavoidable.
Though you can still use the reduce method without converting your array into a set like this:
var tempH = [Int]()
let c = h.reduce(0) { (result, item) in
if (!tempH.contains(item)) {
tempH.append(item)
return h.contains(item+1) ? (result + 1) : result
}
else {return result}
}
But, as you can notice in above code, we have to use a temporary array to track our duplicates. Hence an extra variable seems unavoidable here. Though no Sets are being used in above code.

Swift splitting UILabel between two lines

Here's a picture of a UILabel getting split between two lines:
I'm okay with it getting split, but it's getting split awkwardly. Is there any way to distribute the text more evenly between the two lines? I.e. to have three words (no pun intended) on each line in this case. The string is coming from user input, so I need a solution that works for any string (character limit is 40). Also, I'm doing this programatically. Thanks!
Add a linebreak \n to the text where you want the split to happen.
EDIT
Here is a solution that splits the string in roughly half, based on spaces:
var str = "Hello, label, here is some variable text"
let length = str.characters.count // 40
var splitRange = str.range(of: " ", options: String.CompareOptions.literal, range: str.index(str.startIndex, offsetBy: length / 2)..<str.endIndex, locale: nil) // finds first space after halfway mark
var firstLine = str.substring(to: splitRange!.lowerBound) // "Hello, label, here is"
var secondLine = str.substring(from: splitRange!.upperBound) // "some variable text"

OpenOffice Compare two cell strings

So I am working on a macro in Basic, and where I'm at now I need to compare two columns for duplicates.
Here's what I have going so far:
for i = 0 To 5
Cell1 = Sheet.getCellByPosition(0,i)
for j = 0 to 5
Cell2 = Sheet.getCellByPosition(1,j)
rem COMPARISON WOULD HAPPEN HERE
Next j
Next i
I would like to do something along the lines of: if Cell1.String == Cell2.String then ...
This is my first attempt at writing a macro and so I would greatly appreciate any help and/or guidance.
Thanks!
Also on a side note if anyone know of good tutorials.documentation for this other than wiki, I would be extremely grateful for the link
You should store all values of the first column into an array and then compare every value of the second column with all entries of the array using a simple recursion.
A code that may work is
Dim firstcolumn(5) As String
For i = 0 to 5
firstcolumn(i) = Sheet.getCellByPosition(0,i)
Next i
For j = 0 to 5
Cell2 = Sheet.getCellByPosition(1,j)
for i = 0 to 5
if Cell2 = firstcolumn(i) then
MsgBox("The value of the cell " + i + " in the first column is the same with the value of the cell " + j + " of the second column")
Next i
Next j
The best place to look for code samples is the openoffice forum https://forum.openoffice.org/en/forum/
I hope that the above will help you.