Convert [(Key: String, Value: String)] in [String:String]

convert [(key: String, value: String)] in [String:String]

You just need to iterate through the array of tuples and set the key-value pair of your dictionary with the values of the tuple.

var keyValuePairs: [(key: String, value: String)] = [(key: "2017 01 04", value: "143.65"), (key: "2017 01 05", value: "140.78"), (key: "2017 01 06", value: "150.23")]

var dictionary = [String:String]()
keyValuePairs.forEach{
dictionary[$0.0] = $0.1
//since you have named tuples, you could also write dictionary[$0.key] = $0.value
}
print(dictionary)

Please make sure you conform to the Swift naming convention, which is lower-camelcase for variable names.

Swift: convert [Dictionary String, [String : Double] .Element] to [String : [String : Double]]

I would use reduce(into:) for this

let dictionary = decodedModel.reduce(into: [:]) { 
$0[$1.name] = $1.model
}

Cannot convert return expression of type '[(key: String, value: Int)]' to return type '[String : Int]'

You can use Dictionary(uniqueKeysWithValues:) and map the entitlements array to an array of tuples to get the correct input format for the init.

func simplify() -> [String: Int] {
Dictionary(uniqueKeysWithValues: entitlements.map{ ($0.type, $0.entitlement) })
}

If you need to handle duplicate keys there is also a variant that takes a closure for handling what to do. Here is an example based on Apples doc where the first key is always selected

func toDictionary() -> [String: Int] {
Dictionary(entitlements.map { ($0.type, $0.entitlement) },
uniquingKeysWith: { (first, _) in first })
}

Cannot convert value of type '(key: String, value: AnyObject)' to expected argument type '[String : AnyObject]'

  • First of all classes are supposed to be named in singular form Post / ThumbImage. The datasource array e.g. posts contains Post instances and each Post instance contains an array thumbnailImages of ThumbImage instances. These semantics make it easier to understand the design.
  • Second of all JSON dictionaries in Swift 3+ are [String:Any]
  • Third of all according to the initialization rules the super call must be performed after initializing all stored properties.

The value of key thumbnail_images is a dictionary containing dictionaries. The error occurs because you are using the array enumeration syntax which treats the dictionary as an array of tuples.

The dictionary can be parsed to use the key as size name and the value to pass the parameters.

I have no idea why you are using NSObject subclasses but I'm sure you have your reasons.


This is the Thumbnail class

class ThumbImage: NSObject {

let size: String
var url : URL?
let width : Int
let height : Int

init(size : String, parameters: [String: Any]) {

self.size = size
if let urlString = parameters["url"] as? String {
self.url = URL(string: urlString)
}
self.width = parameters["width"] as? Int ?? 0
self.height = parameters["height"] as? Int ?? 0
super.init()
}
}

and this the Post class

class Post: NSObject {

var title: String
var excerpt: String
var content: String
var thumbnailImages = [ThumbImage]()

init(dict: [String: Any])
{
self.title = dict["title"] as? String ?? ""
self.excerpt = dict["excerpt"] as? String ?? ""
self.content = dict["content"] as? String ?? ""
super.init()
if let images = dict["thumbnail_images"] as? [String: [String:Any] ] {
for (key, value) in images {
thumbnailImages.append(ThumbImage(size: key, parameters: value))
}
}
}
}

How to convert list of keyvalue pairs to list of string (key,value) in C#?

Work with .Select() from System.Linq to convert Key-Value pair to string.

using System.Linq;

Dictionary<string, string> dict = new Dictionary<string, string>
{
{ "Key1", "Value1" },
{ "Key2", "Value2" },
{ "Key3", "Value3" }
};

List<string> result = dict
.Select(x => $"{x.Key},{x.Value}")
.ToList();

Sample program

Convert scala string to key value pairs

you can use .split("pattern").

val data = """key1-value1,value2"""

val kv = data.split("-") match {
case Array(h, t) =>
t.split(",").map(value => (h, value)).toList
}

println(kv)

output:

List((key1,value1), (key1,value2))

Initializing a Dictionary(uniqueKeysWithValues:) from KeyValuePairs

It's because KeyValuePairs.Element has labels.

type(of: (key: "", value: 0)) == type(of: ("", 0)) // false

You need another overload or just an in-place removal of the labels.

public extension Dictionary {
/// Creates a new dictionary from the key-value pairs in the given sequence.
///
/// - Parameter keysAndValues: A sequence of key-value pairs to use for
/// the new dictionary. Every key in `keysAndValues` must be unique.
/// - Returns: A new dictionary initialized with the elements of
/// `keysAndValues`.
/// - Precondition: The sequence must not have duplicate keys.
@inlinable init<Elements: Sequence>(uniqueKeysWithValues keysAndValues: Elements)
where Elements.Element == Element {
self.init(
uniqueKeysWithValues: keysAndValues.map { ($0, $1) }
)
}
}
XCTAssertEqual(
Dictionary(
uniqueKeysWithValues: ["quot;: "quot;, "‍♀️": "‍♂️"] as KeyValuePairs
),
.init(
uniqueKeysWithValues: [("quot;, "quot;), ("‍♀️", "‍♂️")]
)
)

Convert dictionary values from string to double when there are 5 values per key

The problem here is that your dollar values are not numbers, they are Strings.

Put this in a Playground:

import Foundation

let jsonData = """
{
"Time Series (Daily)": {
"2021-09-22": {
"1. open": "402.1700",
"2. high": "405.8500",
"3. low": "401.2600",
"4. close": "403.9000",
"5. volume": "5979811"
},
"2021-09-21": {
"1. open": "402.6600",
"2. high": "403.9000",
"3. low": "399.4400",
"4. close": "400.0400",
"5. volume": "6418124"
}
}
}
"""
.data(using: .utf8)!

struct ReadData {
let timeSeriesDaily: [Date: TimeSeriesDaily]
}

struct TimeSeriesDaily {
let open: Double
let high: Double
let low: Double
let close: Double
let volume: Double
}

extension ReadData: Decodable {
enum CodingKeys: String, CodingKey {
case timeSeriesDaily = "Time Series (Daily)"
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
timeSeriesDaily = Dictionary(
uniqueKeysWithValues: try container
.decode([String: TimeSeriesDaily].self, forKey: .timeSeriesDaily)
.map { (dateFormatter.date(from: $0)!, $1) }
)
}
}
/** In the above, the container can decode [String: T] but it can't decode [Date: T], so we convert the Strings to Dates using a dateFormatter */

extension TimeSeriesDaily: Decodable {
enum CodingKeys: String, CodingKey {
case open = "1. open"
case high = "2. high"
case low = "3. low"
case close = "4. close"
case volume = "5. volume"
}

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
open = Double(try container.decode(String.self, forKey: .open))!
high = Double(try container.decode(String.self, forKey: .high))!
low = Double(try container.decode(String.self, forKey: .low))!
close = Double(try container.decode(String.self, forKey: .close))!
volume = Double(try container.decode(String.self, forKey: .volume))!
}
}
/** Since the values in the json are actually Strings, we decode them as such and then convert to Doubles. */
let dateFormatter: DateFormatter = {
let result = DateFormatter()
result.dateFormat = "yyyy-MM-dd"
return result
}()

print(try JSONDecoder().decode(ReadData.self, from: jsonData))

If you don't like all the force casting, you can bring in a castOrThrow type function.



Related Topics



Leave a reply



Submit