Rohit
Rohit

Reputation: 2326

How to make the combination of elements from an array and display on tableView in swift

I have an array like this:-

var priceArray = [0, 200, 400, 600, 800, 1000]

I got this data from an Api in my app. And I am using tableView to Show data So I can provide the selection of prices like this: -

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return priceArray.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "stickCell", for: indexPath) as! StcikCell
    cell.priceLabel.text = "\(priceArray[0]) - \(priceArray[1])"
    return cell
}

But the problem is if I will use this:

cell.priceLabel.text = "\(priceArray[0]) - \(priceArray[1])" 

I will get only the first and second value in tableView But what I actually want is in first row I want to get 0 - 200 then in second row 200 - 400 in third 400 - 600 and so on until I will get the combination of 800 - 1000. How can I do this. Please help?

Upvotes: 1

Views: 110

Answers (6)

Stanislau Baranouski
Stanislau Baranouski

Reputation: 1451

All you need is to prepare dataSource properly.
To do that, I recommend to split existing price array into chunks and map it to objects you want to represent. In your case String type.
You can use following extension:

extension Sequence {
func split(by chunkSize: Int) -> [[Self.Element]] {
    return self.reduce(into:[]) { memo, cur in
        if memo.count == 0 {
            return memo.append([cur])
        }
        if memo.last!.count < clump {
            memo.append(memo.removeLast() + [cur])
        } else {
            memo.append([cur])
        }
    }
}
}

Usage:

var priceArray = [0, 200, 400, 600, 800, 1000]
let dataSource = priceArray.split(by: 2).map { "\($0[0]) - \($0[1])" }
// result: ["0 - 200", "400 - 600", "800 - 1000"]

Upvotes: 1

rubik
rubik

Reputation: 602

You can simply create function for creating dataSource array for your tableView:

func makeTableDataSource(from priceArray: [Int]) -> [String] {
    var resultArray = [String]()

    for (index, price) in priceArray.enumerated() where index < priceArray.count - 1 {
        resultArray.append("\(price) - \(priceArray [index + 1])")
    }

    return resultArray
}

Results of it:

    var priceArray = [0, 200, 400, 600, 800, 1000]

    Result:
    - 0 : "0 - 200"
    - 1 : "200 - 400"
    - 2 : "400 - 600"
    - 3 : "600 - 800"
    - 4 : "800 - 1000"

    var priceArray = [0, 200, 400]

    Result:
    - 0 : "0 - 200"
    - 1 : "200 - 400"

    var priceArray = [0]

    Result:
    []

After that, just create property like private var tableViewDataSource = [String]() Then in your viewDidLoad() add:

override func viewDidLoad() {
    super.viewDidLoad() 
    var priceArray = [0, 200, 400, 600, 800, 1000] 
    tableViewDataSource = makeTableDataSource(from: priceArray)
}

And it's easy to use in your case:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tableViewDataSource.count 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "stickCell", for: indexPath) as! StcikCell
    cell.priceLabel.text = tableViewDataSource[indexPath.row]
    return cell
}

Pros of this approach:

  • you create your data source only once when open viewController
  • datasource for your cell not generating "on the fly"
  • single responsibility for generating tableDataSource data (if you'll need to update strings, you need todo it only in makeTableDataSource, and everything else work fine)
  • potentially errors easy to locate
  • single "data of trues" for all table (you don't need use array.count - 1, or array.count + 1 in different cases, so less places for potentially crashes)
  • and you can reuse this function of course :)

Happy coding!

Upvotes: 1

Prashant Dabhi
Prashant Dabhi

Reputation: 11

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return priceArray.count - 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "stickCell", for: indexPath) as! StcikCell


    cell.priceLabel.text = "\(priceArray[indexPath.row]) - \(priceArray[indexPath.row + 1])"


        return cell
    }

Upvotes: 1

David Pasztor
David Pasztor

Reputation: 54716

You need to use indexPath.row to index priceArray in cellForRowAt and also need to modify numberOfRowsInSection since there are less price ranges than the number of elements in priceArray.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return priceArray.count - 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "stickCell", for: indexPath) as! StcikCell
    cell.priceLabel.text = "\(priceArray[indexPath.row]) - \(priceArray[indexPath.row+1])"
    return cell
}

Upvotes: 2

Viren Malhan
Viren Malhan

Reputation: 115

Your price array has 6 elements. but you need 5 price range. So you need to minus 1 from numberOfRowsInSection, that will give you 5 element.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return priceArray.count - 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "stickCell", for: indexPath) as! StcikCell
    cell.priceLabel.text = "\(priceArray[indexPath.row]) - \(priceArray[indexPath.row+1])"
    return cell
}

Upvotes: 1

Aakash
Aakash

Reputation: 2269

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return (priceArray.count - 1)
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "stickCell", for: indexPath) as! StcikCell
    let index = indexPath.row
    cell.priceLabel.text = "\(priceArray[index]) - \(priceArray[index + 1])"
    return cell
}

This should do the job.

Upvotes: 1

Related Questions