简体   繁体   中英

Swift 5 How can I hash two arrays

How can I make this code SWIFT accepting? I've got two arrays of type ANY one array's value should act as the key, the other one as the appropriate value:

let it_tt_ar  = db.pair(keys: "int_test", values: "text_test");
func _pair<K : Hashable, V>(keys: [K], values: [V]) -> Dictionary<K,V> {
    
            var result = Dictionary<K, V>();

            for i in 0...(keys.count - 1) {
                result[keys[i]] = values[i];
            }

            return result;
    }
    
func pair (keys: String?, values: String?) -> Dictionary<Int32,Any> {
    
        if let _keys = keys, let _values = values {

            let result = _pair(keys: hashtable[_keys] as! [Int32], values: hashtable[_values]!);
            
            return result;
            
        } else {
            
            return [:];
        }
    }

I can't get it working if the type of the key is unknown. I want to write it like this:

let it_tt_ar  = db.pair<Int32,String>(keys: "int_test", values: "text_test");

or

let it_tt_ar  = db.pair(keys: "int_test", values: "text_test", kt:(Int32.self,String.self));

... in the last case by catching kt: in the function

But there's seems no chance to win against SWIFT:

  • cannot specify generic functions or
  • Int32 cannot fulfill the hashable protocol

It's terrible! You want to write application logic but 80% of the development time is wasted by got to have fulfill such rules!

It looks like you're trying to turn a pair of arrays into a dictionary, regardless of the type of the array (provided, of course, that the type of the key array element is hashable). Here is one way:

let k : [Int] = [1,2,3]
let v : [String] = ["one", "two", "three"]

func pair<Key, Value>(keyArray keys:[Key], valueArray values:[Value]) -> Dictionary<Key,Value> where Key:Hashable {
    zip(keys,values).reduce(into: Dictionary<Key,Value>()) { 
        (dict, tuple) in dict[tuple.0] = tuple.1
    }
}
let result = pair(keyArray: k, valueArray: v)
print(result) // [1: "one", 2: "two", 3: "three"], in some order

Found a solution that works for me:

var db = try DataBaseSqlite(dbfile: "test.db");

try db.select(sql: "int_test, real_test, text_test from stest");

var it = db.valueByKey(key: "int_test");
var rt = db.valueByKey(key: "real_test");
var tt = db.valueByKey(key: "text_test");

let it_tt_ar  = db.pair(keys: "int_test", values: "text_test", kt: Int32.self);
let tt_it_ar  = db.pair(keys: "text_test", values: "int_test", kt: String.self);

try db.close();
func _pair<K : Hashable, V>(keys: [K], values: [V]) -> Dictionary<K,V> {
    
            var result = Dictionary<K, V>();

            for i in 0...(keys.count - 1) {
                result[keys[i]] = values[i];
            }

            return result;
    }
    
    func pair<T>(keys: String?, values: String?, kt: T.Type) -> Dictionary<T,Any> {
    
        if let _keys = keys, let _values = values {

            let result = _pair(keys: hashtable[_keys] as! [T], values: hashtable[_values]!);
            
            return result;
            
        } else {
            
            return [:];
        }
    }

Due to lack of supporting a real hashtable in Swift (like c# does), my hashtable is just an Dictionary of <String,Array> which is automatically built up by the select method. So from an application point of view I can write a more efficient and generic code to query sqlite databases.

dbValueByKey() returns a typed (requested) Array of the column values and pair() returns just a combination of two columns.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM