Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3 Feature Requests: 1) compounding 2) struct to dictionary 3) kwargs #111

Open
Lincoln-Hannah opened this issue Sep 19, 2022 · 3 comments
Open

Comments

@Lincoln-Hannah
Copy link

Lincoln-Hannah commented Sep 19, 2022

using Dictionaries, Parameters, NamedTupleTools, Lazy

# 1-   Compounding 2 dictionaries.   
#       d1, d2 joined on values(d1)=keys(d2).    Resulting Dictionary maps keys(d1) to values(d2)

compound(d1::Dictionary,d2::Dictionary) = @>>    d1    filter(∈(keys(d2)))     map(y->d2[y])

#        allow the compound function to also take arguments that can be converted to dictionaries

compound(iterable1 ,iterable2 ) = compound( Dictionary(iterable1),  Dictionary(iterable2)   )


#         infix operator

⊚(d1,d2) = compound(d1,d2)      


# 2-   Create Dictionary from struct

DictfromStruct = Dictionary ∘ ntfromstruct

#         would prefer to add a method Dictionary(x::struct) but ::struct   doesn't exist.
#         (ntfromstruct uses isstructtype to throw error if input isn't a struct. But this is in the function body)


# 3-    Allow Dictionary to be kwargs in the same way Dict can.      e.g.   f(;  d... )



###########       EXAMPLE       ###################################################
###################################################################################

@enum Currency AUD GBP CAD JPY

FX_Rates = Dictionary( [AUD,GBP,CAD,JPY], [0.7,1.2,0.9,101] )

@with_kw struct Trade 
    C1::Currency
    C2::Currency
    other::Float
end

value( t::Trade; C1::Float, C2::Float) = t.other * C1 * C2

trade_1 = Trade( C1=AUD, C2=GBP, other=10)


#         I'd like the below to produce   Dictionary( [:C1,:C2],[0.7,1.2])
#         Infix operator calls compound function which converts trade_1 to Dictionary then compounds it with FX_Rates

trade_1 ⊚ FX_Rates     


#          using  #3-   I'd like to call the value function with

value( trade_1;   (trade_1 ⊚ FX_Rates)... )
@andyferris
Copy link
Owner

andyferris commented Sep 19, 2022

Interesting! Let me go in reverse order:

3 - I love the keyword argument idea! On the reverse side I had been toying with idea of overloading getproperty to let you fetch Symbol keys.

2 - Given 3, in recent versions of Julia users could type Dictionary(; struct...). Is that right? Given that, should we just document that rather than adding methods that have to infer if something is struct-ish or not?

1 - Is this the same operation as getindices from Indexing.jl?

For 1, I do think we need to solve this somehow. Sometimes I think about this in terms of tabular data - we have one-one joins, many-one joins and many-many joins. The one-one primary key to primary key join is just merge. The many-one foreign key to primary key join is like this "compound". I think many-many should generally rely on the user to reindex data - e.g. with group from SplitApplyCombine.jl or similar (or using innerjoin from SplitApplyCombine.jl).

@Lincoln-Hannah
Copy link
Author

Lincoln-Hannah commented Sep 20, 2022

3- By overloading getproperty. Do you mean the ability to write Dict.key instead of Dict[:key] ?
This is what DotMaps.jl does. It works for a Dict but not a Dictionary
A nice feature to have sometimes.

2 - (; struct...) Doesn't work on 1.8.0. I use ntfromstruct() from NamedTupleTools.jl. So maybe could just document to use Dictionary ∘ ntfromstruct
Would be great if it could be done in a Dictionary() method but I think "struct-ish" can only be determined in the function body (not in the first line where the types are specified.)

1- You're right getindices does this.
Though getindices( d1, d2 ) fails for any d2 value that not matching a d1 key.
Could there be an option to exclude these and return a Dictionary with keys = intersect( keys(d1), values(d2) )

I really like the relational database analogy. I'm most interested in the PK-FK relationship. I'll add an example.

@Lincoln-Hannah
Copy link
Author

using WhereTraits, NamedTupleTools

@traits Dictionary( x ) where isstructtype(typeof(x)) = Dictionary( ntfromstruct( x ))

Could do this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants