Extracting values from arbitrary MathLink.WExpr
Closed this issue · 8 comments
Hi:
Is there a way to parse outputs like these into julia?
W"Association"(W"Rule"("baseSalary", W"Quantity"(220000, "USDollars")), W"Rule"("position", "F"))
Thanks,
Gani -
Hi. Can you clarify a bit here. What would be the corresponding Mathematica code?
Sorry, yes! I was playing with a toy Association and here is one example.
a=weval(W`chingAssociation = Association["team" -> "HOU", "lastName" -> "Ching", "firstName" -> "Brian", "position" -> "F", "baseSalary" -> Quantity[220000, "USDollars"], "guaranteedSalary" -> Quantity[220000, "USDollars"], "year" -> DateObject[{2007}, "Year", "Gregorian", -5.\`]]; c=chingAssociation[[{"baseSalary","position"}]]`)
Output
W"Association"(W"Rule"("baseSalary", W"Quantity"(220000, "USDollars")), W"Rule"("position", "F"))
Thanks!
sorry, I should have made it clearer. I would like the output (22000,"F") if that is possible.
thx!
Hi, the behavior you are describing is not the same as the matiamatica behaviour so it would be unwise to implement it.
In[1]:= chingAssociation=Association["team"->"HOU","lastName"->"Ching","firstName"->"Brian","position"->"F","baseSalary"->Quantity[220000,"USDollars"],"guaranteedSalary"->Quantity[220000,"USDollars"]]
Out[1]= <|team->HOU,lastName->Ching,firstName->Brian,position->F,baseSalary->$ 220000,guaranteedSalary->$ 220000|>
In[2]:= c=chingAssociation[[{"baseSalary","position"}]]
Out[2]= <|baseSalary->$ 220000,position->F|>
you can howerver acces individual elements directly:
In[3]:= c["baseSalary"]
Out[3]= $ 220000
In[4]:= {c["baseSalary"], c["position"]}
Out[4]= {Quantity[220000, "USDollars"], "F"}
In Julia and MathLink
this could be done by mapping the Association
to a Julia dictionary
function WAssociationToDict(Asso::MathLink.WExpr)
Wprint(Asso)
if Asso.head != W"Association"
error("Not an association")
end
D=Dict()
for Rule in Asso.args
if Rule.head != W"Rule"
error("not a rule")
end
if length(Rule.args) != 2
error("Bad rule")
end
D[Rule.args[1]]=Rule.args[2]
end
return D
end
Running the code could the look something like this:
julia> Ass = weval(W`Association["team" -> "HOU", "lastName" -> "Ching", "firstName" -> "Brian", "position" -> "F", "baseSalary" -> Quantity[220000, "USDollars"], "guaranteedSalary" -> Quantity[220000, "USDollars"], "year" -> DateObject[{2007}, "Year", "Gregorian", -5.]]`)
W"Association"(W"Rule"("team", "HOU"), W"Rule"("lastName", "Ching"), W"Rule"("firstName", "Brian"), W"Rule"("position", "F"), W"Rule"("baseSalary", W"Quantity"(220000, "USDollars")), W"Rule"("guaranteedSalary", W"Quantity"(220000, "USDollars")), W"Rule"("year", W"DateObject"(W"List"(2007), "Year", "Gregorian", -5.0)))
julia> D = WAssociationToDict(Ass)
Dict{Any, Any} with 7 entries:
"baseSalary" => W"Quantity"(220000, "USDollars")
"guaranteedSalary" => W"Quantity"(220000, "USDollars")
"year" => W"DateObject"(W"List"(2007), "Year", "Gregorian", -5.0)
"team" => "HOU"
"lastName" => "Ching"
"firstName" => "Brian"
"position" => "F"
julia> D["year"]
W"DateObject"(W"List"(2007), "Year", "Gregorian", -5.0)
julia> D["team"]
"HOU"
julia> [D[x] for x in ["year","team"]]
2-element Vector{Any}:
W"DateObject"(W"List"(2007), "Year", "Gregorian", -5.0)
"HOU"
@gganapat: Would a function like WAssociationToDict
be usefull?
Thanks to your tip, I learned that you can extract individual elements. So,
Ass.args[5].args[2].args[1] = 220000
It is now possible to extract arbitrary elements from the returned MathLink.WExpr object, which gives me a great sense of control! Thanks again!
Gani -
Hi @gganapat, I hope you will like this latest feature (W2Julia
)that i have sneaked into the 0.5.3 (https://github.com/JuliaInterop/MathLink.jl/releases/tag/v0.5.3) release from today. It aims to convert MathLink objects to Julia style objects.
For instance it can convert the "Assumptions" to a dictionary. Below are some examples:
@test W2Julia(W`{1,2,3}`) == [1,2,3]
@test W2Julia(W`{1,a,3}`) == [1,W"a",3]
@test W2Julia(W`{1,a,{1,2}}`) == [1,W"a",[1,2]]
@test W2Julia(W`Association["team" -> "HOU", "lastName" -> "Ching"]`) == Dict( "team" => "HOU" , "lastName" => "Ching")
@test W2Julia(W`Association["team" -> {1,2,3}, "lastName" -> "Ching"]`) == Dict( "team" => [1,2,3] , "lastName" => "Ching")
@test W2Julia(W`{1,Association["team" -> {1,2,3}, "lastName" -> "Ching"]}`) == [1,Dict( "team" => [1,2,3] , "lastName" => "Ching")]
I think this closes the original query.
The function W2Julia
is still quite limited, so if you find something that is missing (which is likely), please open a new ticket and I will fix it.