0

I have a dictionary which contains key and items model for the values.

var selectedDic: [String: [Item]] = [:]

  • Actually I am trying to make a string with dictionary key and key has multiple value separated by comma.
  • And if I add more values to key it should add values to specific key.
  • price and publisher are keys and itemId is the value.

I need this string: price:10-25;publisher:576,925,1737

Dictionary Print:

[
  "price": [
    Babil.Item(name: Optional("10 - 25"),
    itemId: Optional("10-25"))
  ],
  "publisher": [
    Babil.Item(name: Optional("ABCD"),
    itemId: Optional("576")),
    Babil.Item(name: Optional("DEFG"),
    itemId: Optional("925")),
    Babil.Item(name: Optional("HIJK"),
    itemId: Optional("1737"),
    )
  ]
]

My code:

 var itemString: [String: String] = [:]
 var str: [String] = []
        
   for (key, value) in selectedDic {
            value.forEach { a in
                if str.firstIndex(of: key) == nil {
                    str.append(a.itemId!)
                }
            }
            
            let final = str.joined(separator: ",")
            itemString.updateValue(final, forKey: key)
            
        }
2
  • let priceStr = itemString["price"]?.compactMap{ $0.name }.joined(separator: ","); let publisherStr = itemString["publisher"]?.compactMap{ $0.itemId } .joined(separator:","); let finalStr = [priceStr, publisherStr].compactMap{ $0 }.joined(separator: ";") or something like that? But it would help to know what's your current output, can there be more than one price? Why use a Dict and not another custom struct? Why name AND itemId are BOTH optional in Item? Is that normal? Commented Feb 18, 2021 at 12:02
  • @Larme Thank you first of all. But before creating string it duplicates value to other keys as well. see - ["price": "10-25", "publisher": "10-25,576,925,1737"] 10-25 in publisher too. Commented Feb 18, 2021 at 12:06

2 Answers 2

1

With:

struct Item {
    let name: String?
    let itemId: String?
}

let dict: [String: [Item]] = ["price": [Item(name: "10-25", itemId: "10-25")],
                              "publisher": [Item(name: "ABCD", itemId: "576"),
                                            Item(name: "DEFG", itemId: "925"),
                                            Item(name: "HIJK", itemId: "1737")]]


You could use:

var keys = ["price", "publisher"]
let reduced = keys.reduce(into: [String]()) { result, current in
    guard let items = dict[current] else { return }
    let itemsStr = items.compactMap {$0.itemId }.joined(separator: ",")
    result.append("\(current):\(itemsStr)")
}
let finalStr = reduced.joined(separator: ";")
print(finalStr)

The idea: Iterate over the needed keys (and order guaranteed), construct for each keys, the itemsIds list joined by "," and then append that with the key. Finally, joined all that.

Add-on questions: Why is name and itemId optional? Is that normal?

Site note: giving the first part (easily reproducible input) can increase the change of answers, so we don't have to recreate ourselves fake data to check our answers.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. name and itemId yes normal at the moment back end service are on initial phase.
0

Try this: The order of the keys can be different since it is a dictionary and order isn't signficant in a dict

print(
    yourDict.map { (key, values) -> String in
        "\(key): \(values.compactMap { $0.itemId }.joined(separator: ","))"
    }.joined(separator: ";") 
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.