fill dictionary with data - arrays

I want to fill the dictionary with data, so that it looks like this:
1:Apple
2:Banana
3:Lemon
Sorry, if this is too simple for probably most of you - I am just a beginner. Anyway, here is the code:
var listOfFruit = ["Apple", "Banana","Lemon"]
var key = [1,2,3]
var dictionary = [Int: [String]]()
func createDictionary(){
for index in key {
dictionary[index] = []
var listOfFruit = ["Apple", "Banana","Lemon"]
for index1 in listOfFruit{
dictionary[index]?.append(index1)
}
}
}
print(dictionary)
The result of the above is "[:]\n" in my playground.

A functional approach to creating your dictionary could look like this:
let dictionary = zip(listOfFruit, key).map { [$1: $0] }
print(dictionary)
// [[1: "Apple"], [2: "Banana"], [3: "Lemon"]]

let listOfFruit = ["Apple", "Banana","Lemon"]
let key = [1,2,3]
var dictionary = [Int: String]()
func createDictionary(){
var i = 0
while i < listOfFruit.count {
dictionary[key[i]] = listOfFruit[i]
i += 1
}
}
createDictionary()
print(dictionary)
Note the change of the line:
var dictionary = [Int: [String]]()
to:
var dictionary = [Int: String]()
and the use of the variable i to get the same index from each array.

var listOfFruit = ["Apple", "Banana","Lemon"]
var key = [1,2,3]
var dictionary = [Int: String]()
func createDictionary(){
for (index, value) in key.enumerate() {
dictionary[value] = listOfFruit[index]
}
}
createDictionary()
print(dictionary)

Related

How to parse an array to return a collection?

I have a certain model in the form of a structure:
struct ContactsModel {
let name: String
let status: String
let number: String
let onlineStatus: Bool
}
And there is a method that parses the array of names and adds them to the new collection.
var contactsDictionary = [String: [String]]()
var contactNameSectionTitles = [String]()
var names = [String]()
var contactsArray = [ContactsModel(name: "Test", status: "Test", number: "+7 999 999 99 99", onlineStatus: true)]
func configurateDictionary() {
names = contactsArray.map {$0.name}
for value in names {
let nameKey = String(value.prefix(1))
if var namePrefix = contactsDictionary[nameKey] {
namePrefix.append(value)
contactsDictionary[nameKey] = namePrefix
} else {
contactsDictionary[nameKey] = [value]
}
}
contactNameSectionTitles = [String](contactsDictionary.keys)
contactNameSectionTitles = contactNameSectionTitles.sorted(by: { $0 < $1 })
}
How do I do so in the method so that it returns not a string, but a model? I want the collection to be type
var contactsDictionary = [String: [ContactsModel]]()
There is an API to group an array to a dictionary
var contactsDictionary = [String:[ContactsModel]]()
var contactNameSectionTitles = [String]()
func configurateDictionary() {
contactsDictionary = Dictionary(grouping: contactsArray, by: { $0.prefix(1).uppercased() })
contactNameSectionTitles = contactsDictionary.keys.sorted()
}
You need Dictionary grouping by , e.x to group the array by name do
let arr = [ContactsModel]
let res = Dictionary(grouping: arr, by: { $0.name }) // [String:[ContactsModel]]
https://developer.apple.com/documentation/swift/dictionary/3127163-init
This method will return a dictionary of [String: ContactsModel]
func configurateDictionary() -> [String: ContactsModel] {
let result = contactsArray.reduce( [String: ContactsModel](), { (d, e) -> [String: ContactsModel] in
var dict = d
dict[e.name] = e
return dict
})
return result
}
If you want to change the configurateDictionary method to return [String: [ContactsModel]], create a temporary dictionary inside the function and return it at the end of the function
class ViewController: UIViewController {
var contactsDictionary = [String: [ContactsModel]]()
var contactNameSectionTitles = [String]()
var names = [String]()
var contactsArray = [ContactsModel(name: "Test", status: "Test", number: "+7 999 999 99 99", onlineStatus: true)]
override func viewDidLoad() {
super.viewDidLoad()
contactsDictionary = configurateDictionary()
}
func configurateDictionary() -> [String: [ContactsModel]] {
names.removeAll()
contactNameSectionTitles.removeAll()
var temp = [String: [ContactsModel]]()
for contact in contactsArray {
names.append(contact.name)
let nameKey = String(contact.name.prefix(1))
temp[nameKey, default: []].append(contact)
}
contactNameSectionTitles = [String](contactsDictionary.keys).sorted()
return temp
}
}

Swift: Remove repeated Index and create a new dictionary with reversed index and value

I have a dictionary with two Int’s A:B, and I want create a new dictionary that includes B as an index (with no repetition) and A as a value (only for repeated B’s):
var myDict : [Int:Int] = [12:2345, 14:2345, 99:1111, 67:1111, 77:7657, 132:3345, 199:6778]
Desired output:
var newDict: [Int:[Int]] = [2345: [ 12 , 14 ] , 1111: [ 99 , 67] ]
Note: the original dictionary contains over a thousand entries.
You loop through the first dict by enumerating it, that way you can switch the values in to the new dict
var newDict: [Int:[Int]] = [:]
let myDict : [Int:Int] = [12:2345, 14:2345, 99:1111, 67:1111, 77:7657, 132:3345, 199:6778]
for values in myDict.enumerated() {
var newValue = newDict[values.element.value] ?? []
newValue.append(values.element.key)
newDict[values.element.value] = newValue
}
newDict = newDict.filter { (key, value) -> Bool in
value.count > 1
}
Here is the power of swift:
let newDict = Dictionary(grouping: myDict, by: {$0.value}).filter({$0.value.count > 1}).mapValues({$0.map({$0.key})})
print(newDict)
Output: [1111: [67, 99], 2345: [12, 14]]
Please use this code:
var myDict: [Int:Int] = [12:2345, 14:2345, 99:1111, 67:1111, 77:7657, 132:3345, 199:6778]
let values = myDict.values
let tempValueSet = Set<Int>(values)
let uniqueValues = Array(tempValueSet)
var result = [Int: [Int]]()
for item in uniqueValues {
result[item] = myDict.allKeys(forValue: item)
}
print(result)
And this is Dictionary extension:
extension Dictionary where Value: Equatable {
func allKeys(forValue val: Value) -> [Key] {
return self.filter { $1 == val }.map { $0.0 }
}
}
Desired output:
[6778: [199], 1111: [99, 67], 7657: [77], 3345: [132], 2345: [12, 14]]
For more reference about this extension : https://stackoverflow.com/a/27218964/2284065
If you don't want to use extension then you can use this code too :
var myDict: [Int:Int] = [12:2345, 14:2345, 99:1111, 67:1111, 77:7657, 132:3345, 199:6778]
let values = myDict.values
let tempValueSet = Set<Int>(values)
let uniqueValues = Array(tempValueSet)
var result = [Int: [Int]]()
for item in uniqueValues {
result[item] = (myDict as NSDictionary).allKeys(for: item) as! [Int]
}
print(result)

how to combine two dictionary values as a key and value pair in swift

let arra = ["abc","def","abc","def"]
let arra2 = ["addr1","addr2","addr1","addr2"]
Expected Output
dic = ["abc":"addr1","addr1" , def: "addr2","addr2"]
Swift 4's new Dictionary initializer lets you do that kind of thing easily:
let arra = ["abc","def","abc","def"]
let arra2 = ["addr1","addr2","addr1","addr2"]
let dict = [String:[String]](zip(arra,arra2.map{[$0]}),uniquingKeysWith:+)
print(dict) // ["abc": ["addr1", "addr1"], "def": ["addr2", "addr2"]]
[EDIT] Swift 3 equivalent :
var dict : [String:[String]] = [:]
zip(arra,arra2.map{[$0]}).forEach{ dict[$0] = (dict[$0] ?? []) + $1 }
There should be easier way but in general:
import UIKit
let keyArray = ["abc","def","abc","def"]
let valueArray = ["addr1","addr2","addr1","addr2"]
let setFromKeyArray = Set(keyArray)
var finalDict = [String: [String]]()
for index in 0..<keyArray.count {
if let _ = finalDict[keyArray[index]] {
finalDict[keyArray[index]]!.append(valueArray[index])
} else {
finalDict[keyArray[index]] = [valueArray[index]]
}
}
print(finalDict)
// output: ["abc": ["addr1", "addr1"], "def": ["addr2", "addr2"]]
Using zip(_:_:) and reduce(_:_:):
let array1 = ["abc", "def", "abc", "def"]
let array2 = ["addr1", "addr2", "addr1", "addr2"]
let dictionary = zip(array1, array2).reduce([String: String]()) {
var dictionary = $0
dictionary[$1.0] = $1.1
return dictionary
}
print(dictionary) // ["abc": "addr1", "def": "addr2"]
You can use like below :
let arra = ["abc","def","abc","def"]
let arra2 = ["addr1","addr2","addr1","addr2"]
var dictionary: [String: String] = [:]
dictionary.merge(zip(arra, arra2)) { (old, new) -> String in
return "\(old), \(new)"
}
print(dictionary)
Output :
["abc": "addr1, addr1", "def": "addr2, addr2"]
The best of Dennis and Kristijan and Alain.
let arra = ["abc", "def", "abc", "def"]
let arra2 = ["addr1", "addr2", "addr1", "addr2"]
let dict = zip(arra, arra2).reduce([String:[String]]()){
var d = $0
d[$1.0] = ($0[$1.0] ?? []) + [$1.1]
return d
}
print(dict) // ["def": ["addr2", "addr2"], "abc": ["addr1", "addr1"]]
Remember dictionary is unordered.

How to update swift dictionary value

I rewrite this code from php. And I find it difficult to make it work in swift.
var arrayOfData = [AnyObject]()
for index in 1...5 {
var dict = [String: AnyObject]()
dict["data"] = [1,2,3]
dict["count"] = 0
arrayOfData.append(dict)
}
for d in arrayOfData {
let data = d as AnyObject
// I want to update the "count" value
// data["count"] = 8
print(data);
break;
}
Presumably, you want to update the value inside of arrayOfData when you assign data["count"] = 8. If you switch to using NSMutableArray and NSMutableDictionary, then your code will work as you want. The reason this works is that these types are reference types (instead of value types like Swift arrays and dictionaries), so when you're working with them, you are referencing the values inside of them instead of making a copy.
var arrayOfData = NSMutableArray()
for index in 1...5 {
var dict = NSMutableDictionary()
dict["data"] = [1,2,3]
dict["count"] = 0
arrayOfData.addObject(dict)
}
for d in arrayOfData {
let data = d as! NSMutableDictionary
data["count"] = 8
print(data)
break
}
Assuming your array has to be of form '[AnyObject]' then something like this:
var arrayOfData = [AnyObject]()
for index in 1...5 {
var dict = [String: AnyObject]()
dict["data"] = [1,2,3]
dict["count"] = 0
arrayOfData.append(dict)
}
for d in arrayOfData {
// check d is a dictionary, else continue to the next
guard let data = d as? [String: AnyObject] else { continue }
data["count"] = 8
}
But preferably your array would be typed as an array of dictionaries:
var arrayOfData = [[String: AnyObject]]()
for index in 1...5 {
var dict = [String: AnyObject]()
dict["data"] = [1,2,3]
dict["count"] = 0
arrayOfData.append(dict)
}
for d in arrayOfData {
// swift knows that d is of type [String: AnyObject] already
d["count"] = 8
}
EDIT:
So the issue is that when you modify in the loop, you're creating a new version of the dictionary from the array and need to transfer it back. Try using a map:
arrayOfData = arrayOfData.map{ originalDict in
var newDict = originalDict
newDict["count"] = 8
return newDict
}
The most efficient way would be to find the index of the relevant values entry, and then replace that entry. The index is essentially just a pointer into the hash table, so it's better than looking up by key twice:
To update all the entries, you can loop through the indices one at a time:
for i in dictionary.values.indices {
dictionary.values[i].property = ...
}
To update a particular key, use:
let indexToUpdate = dictionary.values.index(forKey: "to_update")
dictionary.values[i].property = ...

value into dictionary with array data - swift

I am really not getting this - why is this not working?
var listOfFruit = ["Apple", "Banana","Lemon"]
var emptyDict = [String: String]()
var key = ["Name of Fruit","Name of Fruit","Name of Fruit"]
func createDictionary(){
var index: Int
index = listOfFruit.count
for index in listOfFruit {
emptyDict = [key[index]:listOfFruit[index]]
print (emptyDict)
}
}
I am getting the usual :
I'm trying to guess what you need because your question is pretty unclear.
IF given this input
var fruits = ["Apple", "Banana","Lemon"]
var keys = ["Name of Fruit", "Name of Fruit", "Name of Fruit"]
you want this output
["Name of Fruit 2": "Lemon", "Name of Fruit 0": "Apple", "Name of Fruit 1": "Banana"]
Then you can use this code
let dict = zip(fruits, keys).enumerate().reduce([String:String]()) { (var result, elm) -> [String:String] in
let key = "\(elm.element.1) \(elm.index)"
let value = elm.element.0
result[key] = value
return result
}
or this code
assert(keys.count == fruits.count)
var dict = [String:String]()
for i in 0..<fruits.count {
let key = "\(keys[i]) \(i)"
let value = fruits[i]
dict[key] = value
}

Resources