0

So I have this method to get an array of random ints between 1-9, a random number of times between 1 and 7.

let n = arc4random_uniform(7) + 1
var arr: [UInt32] = []
for _ in 0 ... n {
    var temp = arc4random_uniform(9) + 1
    while arr.contains(temp) {
        temp = arc4random_uniform(9) + 1
    }
    print(temp)
    arr.append(temp)
}
print(arr)

So that gets me an array like [1,4,2] or [5,7,3,4,6]. And I have a method to turn another array of strings into a enumerated dictionary.

    var someArray: [String] = ["War", "Peanuts", "Cats", "Dogs", "Nova", "Bears", "Pigs", "Packers", "Mango", "Turkey"]

extension Collection  {
    var indexedDictionary: [Int: Element] {
        return enumerated().reduce(into: [:]) { $0[$1.offset] = $1.element }
    }
}
let dict1 = someArray.indexedDictionary
print(dict1)

giving me the indexed dictionary

[1:"War", 2:"Peanuts",..etc]

MY question is using the Ints of the random array how do I create a new dictionary that only includes those keys and their values?

So for example if arr = [3,1,5] how do I get a new dictionary of

[3:"dogs", 1:"Peanuts",5:"Bears"].

vacawama
  • 150,663
  • 30
  • 266
  • 294
Harper Creek
  • 437
  • 6
  • 19

1 Answers1

3

This should do it:

let finalDict = dict1.filter { arr.contains($0.key) }

Update:

You can even go a step further and skip the whole strings to array mapping. So remove

extension Collection  {
    var indexedDictionary: [Int: Element] {
        return enumerated().reduce(into: [:]) { $0[$1.offset] = $1.element }
    }
}
let dict1 = someArray.indexedDictionary
print(dict1)

and just use this:

Swift 4:

let finalArray = someArray.enumerated().flatMap { arr.contains($0.offset) ? $0.element : nil }

Swift 4.1:

let finalArray = someArray.enumerated().compactMap { arr.contains($0.offset) ? $0.element : nil }

Update 2:

If you need a dictionary and not an array in the end use this:

Swift 4:

let finalDict = someArray.enumerated().flatMap { randomInts.contains($0.offset) ? ($0.offset, $0.element) : nil }.reduce(into: [:]) { $0[$1.0] = $1.1 }

Swift 4.1:

let finalDict = someArray.enumerated().compactMap { randomInts.contains($0.offset) ? ($0.offset, $0.element) : nil }.reduce(into: [:]) { $0[$1.0] = $1.1 }
Mihai Fratu
  • 7,579
  • 2
  • 37
  • 63
  • bless you Mihai Fratu – Harper Creek Jun 06 '18 at 20:18
  • You can even skip the array to dictionary mapping by using the second thing – Mihai Fratu Jun 06 '18 at 20:25
  • Could you elaborate on that? How do I incorporate that into my code, and what don't I need and can delete if I use that second thing? – Harper Creek Jun 06 '18 at 20:33
  • Well in your example you have an array of strings that you map to a dictionary, right? You can skip that part - the creation of dict1 - and get your final result directly by using the second method provided. – Mihai Fratu Jun 06 '18 at 20:34
  • When I try to do that I get the error value of type 'EnumeratedSequence<[String]>' has no member 'compactMap' let finalDict = someArray.enumerated().compactMap { arr.contains($0.offset) ? $0.element : nil } – Harper Creek Jun 06 '18 at 20:39
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/172628/discussion-between-mihai-fratu-and-harper-creek). – Mihai Fratu Jun 06 '18 at 20:39
  • When I do cut out the part you suggested, it no longer returns a dictionary, but an array of the chosen elements within the original array. Is this as you expected? – Harper Creek Jun 13 '18 at 00:01
  • Yes, you are right. See my updated answer, once again :) – Mihai Fratu Jun 13 '18 at 12:48