Vuko
Vuko

Reputation: 109

How to map json response and create simple list with indexes

I am getting ingredients, preparings values from response and I want this text to be rendered with breaks, dashes and pointers when displayed on screen. How can I achievie this?

if let ingredients = dict["ingredients"] as? Array<String> {
                    self._ingredients = ingredients.joined(separator: " \n - ")

This works, however not for the first element in array.

4 elements
- 0 : "3 glasses of flour"
- 1 : "1 spoon of salt"
- 2 : "spices"
- 3 : "1 glass of hot water"

I want this to look on ViewController's label, like this:

 - 3 glasses of flour
 - 1 spoon of salt
 - spices
 - 1 glass of hot water

For preparing I want to add appropriate number pointer:

if let preparing = dict["preparing"] as? Array<String> {
                    self._preparing = preparing.joined(separator: "\n")
3 elements
 - 0 : "Mix dry ingredients."
 - 1 : "Add hot water, oil, sugar to yeast."
 - 2 : "When it's ready add this to flour and start combining"

So it looks like this in label:

1. Mix dry ingredients
2. Add hot water, oil and sugar to yeast
3. When it's ready add this to flour and start combining

Additional info Screen of how it look's currently (don't mind language, it's in polish).

And on this Controller's lifecycle I do simple updateUI

func updateUI () {
    pizzaDesc.text = pizza.description
    ingredientsDesc.text = pizza.ingredients
    PreparingDesc.text = pizza.preparings
    titleLbl.text = pizza.title
}

 //MARK: Lifecycle

override func viewDidLoad() {
    super.viewDidLoad()

   hideTestDataOnLoad()
   pizza = PizzaRecipe()
   pizza.downloadRecipeDetails {
        self.updateUI()
    }
}

Upvotes: 2

Views: 217

Answers (2)

MQLN
MQLN

Reputation: 2328

So the reason this is confusing is that there are actually two different things you're trying to accomplish here:

  1. You want to prefix each ingredient with a dash (- 3 eggs)
  2. You want each item of the array on a different line

The problem you're running into is that joined only applies to BETWEEN items in an array, not to EACH item. You need to use .map() {} to do something to every item in an array (think of it like a for-loop).

So you'll achieve that like this:

let prefixed = ingredients.map() {"- " + $0}
let joined = prefixed.joined(separator: " \n")
label.text = joined

Upvotes: 1

OOPer
OOPer

Reputation: 47896

Tested with this dict:

let jsonText = """
{
    "ingredients": [
        "3 glasses of flour",
        "1 spoon of salt",
        "spices",
        "1 glass of hot water"
    ],
    "preparing": [
        "Mix dry ingredients.",
        "Add hot water, oil, sugar to yeast.",
        "When it's ready add this to flour and start combining"
    ]
}
"""
let dict = try! JSONSerialization.jsonObject(with: jsonText.data(using:.utf8)!) as! [String: Any]

Case 1: - may not be a separator.

    if let ingredients = dict["ingredients"] as? Array<String> {
        self._ingredients = ingredients.map{" - \($0)"}.joined(separator: "\n")
        //...
    }

Case 2: You can get element index paired with each element using enumerated().

    if let preparing = dict["preparing"] as? Array<String> {
        self._preparing = preparing.enumerated().map{"\($0+1). \($1)"}.joined(separator: "\n")
        //...
    }

Upvotes: 1

Related Questions