How to map dictionary to object of specific class? - dictionary

I have a given dictionary and want to map it to an object of a specific class.
All keys of the dictionary should be mapped to equally named instance variables of the object.
I guess this is a common procedure? What is the common way to accomplish it?

Consider doing something like this:
dict := { #x -> 5 . #y -> 6 } asDictionary. "dictionary as you described"
basicObj := Point basicNew. "basic instance of your object"
dict keysAndValuesDo: [ :key :val |
basicObj instVarNamed: key put: val ].
^ basicObj

This is indeed a common pattern. It is often used in serialization and materialization. You can find an implementation in
STON

Related

Swiftui: how do you assign the value in a "String?" object to a "String" object?

Swiftui dictionaries have the feature that the value returned by using key access is always of type "optional". For example, a dictionary that has type String keys and type String values is tricky to access because each returned value is of type optional.
An obvious need is to assign x=myDictionary[key] where you are trying to get the String of the dictionary "value" into the String variable x.
Well this is tricky because the String value is always returned as an Optional String, usually identified as type String?.
So how is it possible to convert the String?-type value returned by the dictionary access into a plain String-type that can be assigned to a plain String-type variable?
I guess the problem is that there is no way to know for sure that there exists a dictionary value for the key. The key used to access the dictionary could be anything so somehow you have to deal with that.
As described in #jnpdx answer to this SO question (How do you assign a String?-type object to a String-type variable?), there are at least three ways to convert a String? to a String:
import SwiftUI
var x: Double? = 6.0
var a = 2.0
if x != nil {
a = x!
}
if let b = x {
a = x!
}
a = x ?? 0.0
Two key concepts:
Check the optional to see if it is nil
if the optional is not equal to nil, then go ahead
In the first method above, "if x != nil" explicitly checks to make sure x is not nil be fore the closure is executed.
In the second method above, "if let a = b" will execute the closure as long as b is not equal to nil.
In the third method above, the "nil-coalescing" operator ?? is employed. If x=nil, then the default value after ?? is assigned to a.
The above code will run in a playground.
Besides the three methods above, there is at least one other method using "guard let" but I am uncertain of the syntax.
I believe that the three above methods also apply to variables other than String? and String.

Kotlin convert List with nullables to HashMap without nullables

I have incoming param List<Somedata>.Somedata class contains id field.
My goal is to make HashMap<Somedata.id, Somedata> from this list.
Is next approach correct or there is a better/safer way to do that?
list
.filter { it.id != null }
.associateTo(HashMap(), {it.id!! to it})
Actually, I cannot understand, why should I use !! keyword in associateTo method, when above I filtered it with non-null values only.
Or maybe there is a good way to perform this with ?. or ?.let keywords?
You can do:
list.mapNotNull { e -> e.id?.let { it to e } }.toMap()
Breakdown:
The call to .let with the ?. safe call operator will make the result null if the element is null.
So the lambda passed to mapNotNull is of type (Somedata) -> Pair<IdType, Somedata>.
mapNotNull discards the null pairs, and toMap turns the resulting List<Pair<IdType, Somedata>> into a Map<IdType, Somedata>.
If you want to avoid the creation of an intermediate list to hold the pairs, you can turn the list into a lazy Sequence from the start:
list.asSequence().mapNotNull { e -> e.id?.let { it to e } }.toMap()
Alternatively, since you asked:
why should I use !! keyword in associateTo method, when above I filtered it with non-null values only.
this is because the list is still of type List<Somedata> - this says nothing about the nullability of the field itself. The compiler does not know that the id fields are still not null, by the time your associateTo call is executed.

Find a specific tuple by key in an Erlang list (eJabberd HTTP Header)

I am just getting started with eJabberd and am writing a custom module with HTTP access.
I have the request going through, but am now trying to retrieve a custom header and that's where I'm having problems.
I've used the Request record to get the request_headers list and can see that it contains all of the headers I need (although the one I'm after is a binary string on both the key and value for some reason...) as follows:
[
{ 'Content-Length', <<"100">> },
{ <<"X-Custom-Header">>, <<"CustomValue">> },
{ 'Host', <<"127.0.0.1:5280">> },
{ 'Content-Type', <<"application/json">> },
{ 'User-Agent', <<"Fiddler">> }
]
This is also my first foray into functional programming, so from procedural perspective, I would loop through the list and check if the key is the one that I'm looking for and return the value.
To this end, I've created a function as:
find_header(HeaderKey, Headers) ->
lists:foreach(
fun(H) ->
if
H = {HeaderKey, Value} -> H;
true -> false
end
end,
Headers).
With this I get the error:
illegal guard expression
I'm not even sure I'm going about this the right way so am looking for some advice as to how to handle this sort of scenario in Erlang (and possibly in functional languages in general).
Thanks in advance for any help and advice!
PhilHalf
The List that you have mentioned is called a "Property list", which is an ordinary list containing entries in the form of either tuples, whose first elements are keys used for lookup and insertion or atoms, which work as shorthand for tuples {Atom, true}.
To get a value of key, you may do the following:
proplists:get_value(Key,List).
for Example to get the Content Length:
7> List=[{'Content-Length',<<"100">>},
{<<"X-Custom-Header">>,<<"CustomValue">>},
{'Host',<<"127.0.0.1:5280">>},
{'Content-Type',<<"application/json">>},
{'User-Agent',<<"Fiddler">>}].
7> proplists:get_value('Content-Type',List).
<<"application/json">>
You can use the function lists:keyfind/3:
> {_, Value} = lists:keyfind('Content-Length', 1, Headers).
{'Content-Length',<<"100">>}
> Value.
<<"100">>
The 1 in the second argument tells the function what tuple element to compare. If, for example, you wanted to know what key corresponds to a value you already know, you'd use 2 instead:
> {Key, _} = lists:keyfind(<<"100">>, 2, Headers).
{'Content-Length',<<"100">>}
> Key.
'Content-Length'
As for how to implement this in Erlang, you'd write a recursive function.
Imagine that you're looking at the first element of the list, trying to figure out if this is the entry you're looking for. There are three possibilities:
The list is empty, so there is nothing to compare.
The first entry matches. Return it and ignore the rest of the list.
The first entry doesn't match. Therefore, the result of looking for this key in this list is the same as the result of looking for it in the remaining elements: we recurse.
find_header(_HeaderKey, []) ->
not_found;
find_header(HeaderKey, [{HeaderKey, Value} | _Rest]) ->
{ok, Value};
find_header(HeaderKey, [{_Key, _Value} | Rest]) ->
find_header(HeaderKey, Rest).
Hope this helps.

How convert any record into a map/dictionary in F#?

I need to serialize arbitrary records into maps/dictionary.
I imagine my end type look like this:
type TabularData= array<Map<string, obj>>
But I have problems in build a generic function that accept any record and turn them into Map.
In practice, the best advice is probably to use some existing serialization library like FsPickler. However, if you really want to write your own serialization for records, then GetRecordFields (as mentioned in the comments) is the way to go.
The following takes a record and creates a map from string field names to obj values of the fields. Note that it does not handle nested records and it is not particularly fast:
open Microsoft.FSharp.Reflection
let asMap (recd:'T) =
[ for p in FSharpType.GetRecordFields(typeof<'T>) ->
p.Name, p.GetValue(recd) ]
|> Map.ofSeq
Here is a little example that calls this with a simple record:
type Person =
{ Name : string
Age : int }
asMap { Name = "Tomas"; Age = -1 }
Using the same idea mentioned by Tomas, you can create a IDictionary<K,V> from a record like this:
let asDictionary (entity: 'T) =
seq {
for prop in FSharpType.GetRecordFields(typeof<'T>) ->
prop.Name, prop.GetValue(entity)
} |> dict

What is the difference between a collection of associations and a dictionary in Smalltalk?

| dict |
dict := #{'foo'->'brown'. 'bar'->'yellow'.
'qix'->'white'. 'baz'->'red'. 'flub'->'green'} asDictionary.
dict at: 'qix'
If I PrintIt, I get 'white'. If I remove 'asDictionary', I still get 'white'. What does a dictionary give me that a collection of associations doesn't?
Expression like #{exp1 . sxp2 . exp3} is amber-smalltalkspecific and creates a HashedCollection, which is a special kind of dictionary where keys are strings (probably in Javascript you use things like this a lot).
In other smalltalks there is no expression like that. Instead array expressions which look like: {exp1 . sxp2 . exp3} (there is no leading #) were introduced in squeak and are also available in pharo (which is a fork of Squeak) and Amber. Now the array expression creates an Array and so you have to use integers for #at: message. For example dict at: 2 will return you an association 'bar'->'yellow' because it is on the second position of the array you've created.
#asDictionary is a method of a collection that converts it into a dictionary given that the elements of the collection are associations. So if you want to create a dictionary with keys other than strings, you can do it like this:
dict := {
'foo' -> 'brown' .
1 -> 'yellow' .
3 # 4 -> 'white' .
#(1 2) -> 'red' } asDictionary
A Dictionary is a collection of Associations. It is, in fact, Smalltalk's canonical collection of Associations. (An instance of the Association Class is a key value pair, where the value can be an object of any Class).
The advantage a Dictionary gives you is that it has specialised methods for dealing with Associations, compared to other Collections you might be tempted to use.
A Dictionary provides:
removeKey: aKey . removes aKey
includesKey: aKey . checks for the existence of the key
includes: aValue . checks for the existence of a value
at:put: . shorthand for
anAssociation := Association key:value: .
aDictionary add:
e.g.
anAssociation := Association key: 'Hello'
value: 'A greeting people often use' .
aDictionary add: anAssociation .
If the key already exists in the Dictionary, then at:put will overwrite the pre-existing value with the new value, so it's important to check and make sure that the key has a unique value when adding new items.
Both the key and the value can be an object instance of any Class. Every Association in a Dictionary can be any kind of object, and every single key and value might be a instance of a different Class of object from every other element in the Dictionary.
You can create an Association by
anAssociation := Association key: 'keyOfElement' value: 'valueOfElement'
or, more succinctly,
anAssociation := 'keyOfElement' -> 'valueOfElement'
If you want to use keys entirely made specifically of Symbols, there is also the Class IdentityDictionary

Resources