Array as a Dictionary Value in Swift Language

Array as a dictionary value in swift language

Note that subscript returns an optional. We have to force unwrapping:

println(list[2543]![0])

Or use optional chaining

println(list[2543]?[0])

Swift - Adding value to an array inside a dictionary

EDIT: Thanks to Martin's comment. The snippet below is the the most succinct answer I can think of. I was initially coming at it from a wrong direction. and I was getting an error. See comments

struct Student { 
let id: Int
let subject : String
}

var studentArray = [Student(id: 1, subject: "History"), Student(id: 2, subject: "History"), Student(id:1, subject: "Maths")]

typealias Subject = String
var dict : [Int: [Subject]] = [:]

for student in studentArray {

(dict[student.id, default: []]).append(student.subject)
}

print(dict)

Previous answers:

struct Student { 
let id: Int
let subject : String
}

var studentArray = [Student(id: 1, subject: "History"), Student(id: 2, subject: "History"), Student(id:1, subject: "Maths")]

typealias Subject = String
var dict : [Int: [Subject]] = [:]

for student in studentArray {
var subjects = dict[student.id] ?? [String]()
subjects.append(student.subject)
dict[student.id] = subjects
}

print(dict)

Or you can do it this way:

struct Student { 
let id: Int
let subject : String
}

var studentArray = [Student(id: 1, subject: "History"), Student(id: 2, subject: "History"), Student(id:1, subject: "Maths")]

typealias Subject = String
var dict : [Int: [Subject]] = [:]

for student in studentArray {
if let _ = dict[student.id]{
dict[student.id]!.append(student.subject)
}else{
dict[student.id] = [student.subject]
}
}

print(dict)

whichever you like

How to initialize an array inside a dictionary?

I think you could be misunderstanding something pretty key - let's make sure:

The way the dictionary works, is not to have one array, but an array for each key.

Each value of 'idx' you request the array for returns a different array.

You can't expect it to return an empty array - a dictionary is meant to return a nil value for a key that hasn't been set. To do what you're trying, the following would probably do the trick:

myDict[idx] = myDict[idx] ?? []

Swift: Filter a Dictionary with Array as Value

Here's a solution that maps the values based on the search and then filters out the empty results.

var dictionary = ["a": ["aberration", "abc"], "b" : ["babel", "bereft"]]
var searchText = "aberration"
let filteredDictionary = dictionary.mapValues { $0.filter { $0.hasPrefix(searchText) } }.filter { !$0.value.isEmpty }
print(filteredDictionary)

Output:

["a": ["aberration"]]

Swift 3: Array to Dictionary?

I think you're looking for something like this:

extension Array {
public func toDictionary<Key: Hashable>(with selectKey: (Element) -> Key) -> [Key:Element] {
var dict = [Key:Element]()
for element in self {
dict[selectKey(element)] = element
}
return dict
}
}

You can now do:

struct Person {
var name: String
var surname: String
var identifier: String
}

let arr = [Person(name: "John", surname: "Doe", identifier: "JOD"),
Person(name: "Jane", surname: "Doe", identifier: "JAD")]
let dict = arr.toDictionary { $0.identifier }

print(dict) // Result: ["JAD": Person(name: "Jane", surname: "Doe", identifier: "JAD"), "JOD": Person(name: "John", surname: "Doe", identifier: "JOD")]

If you'd like your code to be more general, you could even add this extension on Sequence instead of Array:

extension Sequence {
public func toDictionary<Key: Hashable>(with selectKey: (Iterator.Element) -> Key) -> [Key:Iterator.Element] {
var dict: [Key:Iterator.Element] = [:]
for element in self {
dict[selectKey(element)] = element
}
return dict
}
}

Do note, that this causes the Sequence to be iterated over and could have side effects in some cases.

Retrieve first dictionary value swift

This should do the trick:

It's a good initiative when learning programming to use manual for loop instead of magical methods like map(), etc, in an algorithmic way. They do loop, but they are implicit.

Here, I used the sorted() (because else it can be a little long).

I also used first(where:), it finds the first non-empty value. It also can be replaced with a while loop, but I didn't know if you wanted a for loop to.

var dict = [1: ["Value-1-1", "", ""],
2: ["", "Value-2-2", "Value-2-3"],
3: ["Value-3-1", "Value-3-2", ""],
4: ["Value-4-1", "", "Value-4-3"],
5: ["", "", "Value-5-3"]]
var finalArray = [String]()
let keys = Array(dict.keys).sorted(by: { return $0<$1 }) // because keys aren't sorted
for aKey in keys {
if let anArrayValue = dict[aKey], let firstNonEmptyValue = anArrayValue.first(where: { !$0.isEmpty }) {
finalArray.append(firstNonEmptyValue)
}
}
print("finalArray: \(finalArray)")

See @Martin R answer for the version with "higher level" methods, but more complicated to understand for debutants (chaining, closures, etc.). It does the same, just more compact, less explicit.

How to Mutate an Array in a Dictionary?

In swift, structures are copied by value when they get assigned to a new variable. So, when you assign a1 to the value in the dictionary it actually creates a copy. Here's the line I'm talking about:

var a1 = d1["a"]!

Once that line gets called, there are actually two lists: the list referred to by d1["a"] and the list referred to by a1. So, only the second list gets modified when you call the following line:

a1.append("s1")

When you do a print, you're printing the first list (stored as the key "a" in dictionary d1). Here are two solutions that you could use to get the expected result.

Option1: Append directly to the array inside d1.

var d1 = [String : [String]]()
d1["a"] = [String]()
d1["a"]?.append("s1")
println(d1)

Option 2: Append to a copied array and assign that value to "a" in d1.

var d1 = [String : [String]]()
d1["a"] = [String]()
var a1 = d1["a"]!
a1.append("s1")
d1["a"] = a1
println(d1)

The first solution is more performant, since it doesn't create a temporary copy of the list.

Swift language: How do I implement a dictionary of array values, and assign (ie. append) new values to the array?


var unloadedRows = imagesRowForLocation(forLocation)
unloadedRows!.append(row)
unloadedImagesRows[forLocation] = unloadedRows!

You retrieve the array by value, i.e. another instance of the array stored inside the dictionary gets created. Therefore you should set it back into the dictionary after appending a value

Appending dictionary values to array in Swift

You should only sort the keys and then use that array to select from the dictionary and append your sortedValues array. I made the sortedKeys into a local variable

func sortItems() {
let sortedKeys = self.dictionary.keys.sorted(by: >)

for key in sortedKeys {
if let obj = dictionary[key] {
self.sortedValues.append(obj)
}
}
}

I don't know if this will make a difference in regard to the crash but another way is to let the function return an array

func sortItems() -> [Object] {
let sortedKeys = self.dictionary.keys.sorted(by: >)
var result: [Object]()

for key in sortedKeys {
if let obj = dictionary[key] {
result.append(obj)
}
}
return result
}

and then call it

self.sortedValues = sortItems()


Related Topics



Leave a reply



Submit