Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build a Dictionary with reduce in Swift

I am trying to use the Swift reduce to build a dictionary from collections in Swift . I have the following variables:

var _squares  : [String] = []
var _unitlist : [[String]] = []
var _units    = [String: [[String]]]()

I want to fill the _units dictionary int the following way:

  • I want to iterate over every element in _squares
  • I want to look at all the lists in _unitlist and filter only the ones that contain the element
  • Build a dictionary that has every single element as a key and the list of lists containing such element as value.

To give you an example. If we have:

squares = ["A"]
unitlist = [["A", "B", "C"], ["A", "C"], ["B", "C", "F"]]

the expected output should be a dictionary di "A" as key and [["A", "B", "C"], ["A", "C"]] as value.

I tried with something like this:

_units = _squares.flatMap { s in
    _unitlist.flatMap { $0 }.filter {$0.contains(s)}
        .reduce([String: [[String]]]()){ (dict, list) in
            dict.updateValue(l, forKey: s)
            return dict
    }
}

I used flatMap twice to iterate, then I filtered and I tried to use reduce.

However, with this code I am facing the following error: Cannot assign value of type '[(key: String, value: [[String]])]' to type '[String : [[String]]]' that is a bit obscure to me.

like image 908
giograno Avatar asked Dec 30 '17 11:12

giograno


2 Answers

let squares = ["A"]
let unitlist = [["A", "B", "C"], ["A", "C"], ["B", "C", "F"]]

let units = squares.reduce(into: [String: [[String]]]()) { result, key in
    result[key] = unitlist.filter { $0.contains(key) }
}
like image 183
Adrian Bobrowski Avatar answered Nov 15 '22 09:11

Adrian Bobrowski


You can iterate over the keys and construct the values by using filter. Here is a playground:

import PlaygroundSupport
import UIKit


let squares = ["A"]
let unitlist = [["A", "B", "C"], ["A", "C"], ["B", "C", "F"]]

func dictionary(keys: [String], containing values: [[String]])  -> [String: [[String]]]{
  var dictionary: [String: [[String]]] = [:]
  keys.forEach { key in
    dictionary[key] = values.filter { $0.contains(key) }
  }
  return dictionary
}

print(dictionary(keys: squares, containing: unitlist))
like image 21
Josh Homann Avatar answered Nov 15 '22 09:11

Josh Homann