I am a novice with regards to the swift 3 programming language though I am familiar basically with C++.
I am trying to learn to use dictionaries in Swift 3; which I believe are similar to hashes in C++. I have a dictionary with several key:value pairs in it.
I want to take a certain, single key (which I won't know in advance) and extract from that dictionary the corresponding value.
I know there will be a single key with that name, although the same value will be associated with keys of different names.
After extracting that value from the key:value pair of that dictionary then I want to store that single value in a variable as a string.
What type of code could do that?
I found some code that seems it might be helpful but I'm not sure and I'm not sure too how to use that code(how to write it actually) to make it perform as I wish.
extension Dictionary where Value: Equatable {
func someKeyFor(value: Value) -> Key? {
guard let index = indexOf({ $0.1 == value }) else {
return nil
}
return self[index].0
}
}
This is straight-forward dictionary access; no need to use extensions.
var myDictionary = [String:String]()
// At some point strings are put into the dictionary
// e.g. myDictionary["SomeKey"] = "SomeString"
// then you can say
if let someString = myDictionary[key] {
// You can now do something with someString
}
Keys and objects don't have to be strings, of course
I would suggest you read the Swift book from Apple in iBooks and try things out in in a Swift Playground in Xcode.
Related
I'm writing a (toy) hash-and-cache decorator in TypeScript and can't find a good means of creating a solid generic one.
The code I have so far is
function cache
(target: Object,
propertyKey: string,
// Likely we can do better than <any> here -- <Function<any>> maybe?
descriptor: TypedPropertyDescriptor<any>)
{
let cacheMap = new Map();
let wrappedFn = descriptor.value;
descriptor.value = function (...args: any[]) {
if (cacheMap.has(args)) {
console.log("Short-circuiting with result: " + cacheMap.get(args));
return cacheMap.get(args);
}
let result = wrappedFn.apply(this, args);
cacheMap.set(args, result);
console.log("cacheMap %o", cacheMap);
return result;
}
return descriptor;
}
Naturally this fails, since args is not a tuple but a list, which is mutable[1]. So each input, even if it's the same over and over, gets its own list/array in its own memory location with its own hash value, wherever that comes from.
I haven't found a Tuple type in TypeScript (or JS) yet -- is there one? Is there another workaround for this sort of problem?
Shouldn't this be an error? Map<T, U> should constrain T to implementing IHashable or something, right? That's the point of types -- to raise this issue before it takes a bunch of time out of your life.
Shouldn't this be an error? Map<T, U> should constrain T to implementing IHashable or something, right?
No. Object identity is a real and well-defined thing in JavaScript; TypeScript doesn't attempt to force you to pretend it doesn't exist.
If the ECMAScript committee thought it was appropriate to enforce non-object-identity-based keying in maps, they could have restricted Map keys, but they didn't.
Basically, I have a function that will transform an object into a different object, and it's like a dictionary, but I don't know how to type it.
var myFunctions = {
a: () => something1,
b: () => something2,
[...]
}
gets transformed into
var myObject = {
a: something1,
b: something2
[...]
}
With Flow 0.33+ you can use $ObjMap
type ExtractCodomain = <V>(v: () => V) => V;
declare function f<O>(o: O): $ObjMap<O, ExtractCodomain>;
I don't think you can do this with Flow. The closest you can get is probably this:
function<T>(obj: T): ([key: $Keys<T>]: boolean)
That function is typed to return an object with the same key as input object, but with boolean-only values (as an example, you can specify another type). Sorry to disappoint, but it's hard to type highly dynamic code with Flow in general.
Note that the $Keys feature is undocumented because it's not part of the public API, so its behavior is defined solely by its implementation (in other words, it can change anytime).
If you're interested in the details of Flow's type system, check out the typings that come with flow in its own /lib directory, for example https://github.com/facebook/flow/blob/master/lib/core.js – you'll see that some things like Object.assign are special-cased, so you might not be able to re-implement such things in your own code.
Also, check out http://sitr.us/2015/05/31/advanced-features-in-flow.html for other "dollar features" such as $Shape and $Diff – it's partially outdated, but can give some good pointers.
#Nikita gave you the best answer for now. That said, the use-case you talked about is being discussed in the issues on the FlowType repository. It may land soon.
As of right now, if you've got mixed type, I'll just fallback to any
function<T>(obj: T): ([key: $Keys<T>]: any)
This way, at least the key names are validated. I expect within a few more versions of Flow, this problem will get solved.
Background:
I am trying to cache some struct information for efficiency but am having trouble differentiating between struct with the same name, within the same package.
Example Code:
func Struct(s interface{}){
val := reflect.ValueOf(s)
typ := val.Type()
// cache in map, but with what key?
typ.Name() // not good enough
typ.PkgPath + typ.Name() // not good enough
}
func Caller1() {
type Test struct {
Name string
}
t:= Test{
Name:"Test Name",
}
Struct(t)
}
func Caller2() {
type Test struct {
Address string
Other string
}
t:= Test{
Address:"Test Address",
Other:"OTHER",
}
Struct(t)
}
Problem
Can't find a proper unique key as:
Name is the same "Test"
PkgPath with be identical as both functions are in same package
Pointers etc is out because need a consistent key otherwise caching would be pointless
Can anyone help in finding a way to uniquely identify these structs?
P.S. I do realize that changing of the struct name would solve the issue, but need to handle this scenario as I have a generic library that others will be calling and may have the structs defined like the above example.
To uniquely identify types in a map, use reflect.Type as the map key:
var cache map[reflect.Type]cachedType
This is recommended by the reflect documentation:
To test for [type] equality, compare the Types directly.
linuxfood has created bindings for sqlite3, for which I am thankful. I'm just starting to learn Rust (0.8), and I'm trying to understand exactly what this bit of code is doing:
extern mod sqlite;
fn db() {
let database =
match sqlite::open("test.db") {
Ok(db) => db,
Err(e) => {
println(fmt!("Error opening test.db: %?", e));
return;
}
};
I do understand basically what it is doing. It is attempting to obtain a database connection and also testing for an error. I don't understand exactly how it is doing that.
In order to better understand it, I wanted to rewrite it without the match statement, but I don't have the knowledge to do that. Is that possible? Does sqlite::open() return two variables, or only one?
How can this example be written differently without the match statement? I'm not saying that is necessary or preferable, however it may help me to learn the language.
The outer statement is an assignment that assigns the value of the match expression to database. The match expression depends on the return value of sqlite::open, which probably is of type Result<T, E> (an enum with variants Ok(T) and Err(E)). In case it's Ok, the enum variant has a parameter which the match expression destructures into db and passes back this value (therefore it gets assigned to the variable database). In case it's Err, the enum variant has a parameter with an error object which is printed and the function returns.
Without using a match statement, this could be written like the following (just because you explicitly asked for not using match - most people will considered this bad coding style):
let res = sqlite::open("test.db");
if res.is_err() {
println!("Error opening test.db: {:?}", res.unwrap_err());
return;
}
let database = res.unwrap();
I'm just learning Rust myself, but this is another way of dealing with this.
if let Ok(database) = sqlite::open("test.db") {
// Handle success case
} else {
// Handle error case
}
See the documentation about if let.
This function open returns SqliteResult<Database>; given the definition pub type SqliteResult<T> = Result<T, ResultCode>, that is std::result::Result<Database, ResultCode>.
Result is an enum, and you fundamentally cannot access the variants of an enum without matching: that is, quite literally, the only way. Sure, you may have methods for it abstracting away the matching, but they are necessarily implemented with match.
You can see from the Result documentation that it does have convenience methods like is_err, which is approximately this (it's not precisely this but close enough):
fn is_err(&self) -> bool {
match *self {
Ok(_) => false,
Err(_) => true,
}
}
and unwrap (again only approximate):
fn unwrap(self) -> T {
match self {
Ok(t) => t,
Err(e) => fail!(),
}
}
As you see, these are implemented with matching. In this case of yours, using the matching is the best way to write this code.
sqlite::open() is returning an Enum. Enums are a little different in rust, each value of an enum can have fields attached to it.
See http://static.rust-lang.org/doc/0.8/tutorial.html#enums
So in this case the SqliteResult enum can either be Ok or Err if it is Ok then it has the reference to the db attached to it, if it is Err then it has the error details.
With a C# or Java background you could consider the SqliteResult as a base class that Ok and Err inherit from, each with their own relevant information. In this scenario the match clause is simply checking the type to see which subtype was returned. I wouldn't get too fixated on this parallel though it is a bad idea to try this hard to match concepts between languages.
I am looking for the equivalent of a foreach loop with keys in Actionscript. In PHP this would be:
foreach($array as $key => $value)
{
}
I found two solutions that will work, but I am wondering if there is a better way to do this. The first solution is to use the for..in loop. Which gives you the keys, but you still have to use the key to access the correct element in your structure. For example:
for(var key:String in results)
{
trace(key + ": " + results[key]);
}
The second option is the for each..in loop, which I believe is new in AS3. With this solution, I can't tell what the keys are. For example:
for each(var row:* in results)
{
trace(row);
}
For the time being, I am going to use for..in. I am just looking for a better way.
Thanks,
Rob
Update: Speed is not a huge deal, because the array is never going to be extremely large. Order does matter, and I would like to get keys in the order of insertion. Here is an example of the array:
sites = {'site1': 34, 'site2': 52, 'site3': 66}
I would like to use the key as well as the value of each entry.
I want to keep my array structure as simple as possible. I could change the sites array above to look like:
sites = {{'name': 'site1', 'id': 34},
{'name': 'site2', 'id': 52},
{'name': 'site3', 'id': 66}}
However, I would rather not go this route, because it adds more dimensions to my array structure.
It depends on your object type. If you're using a Dictionary, you have:
DictionaryUtil.getKeys(myObject)
I wouldn't use for...in unless you're just dumping or purely want the keys and nothing else. It is an object so sort isn't guaranteed and will vary. If sorting isn't an issue, this (for...in or dictionary) is your best bet.
Grant speaks more on dictionary here: http://www.gskinner.com/blog/archives/2006/07/as3_dictionary.html.
for(var i:String in myArray) // loops through the items in the array
myArry[i] += 'new message will show'
for each(var i:String in myArray) // creates a copy of the array as it loops
myArray[i] += 'this change will not show outside the loop';
The later is great for if you need to minipulate the variables during the loop but want to preserve the original object for the rest of your program. Especially handy for formatting or translating values for a specific part of your program.