Crystal associative arrays - associative-array

How do you make associative arrays in Crystal ?
In this case I need an array of bools to configure multiple classes.
Ex :
arr = ??? # what do i place here to make it work ?
arr[:download] = true
arr[:parse] = true
myClass.new(arr)
I do not wish to start gessing were the different values are as time pases ( was download arr[0] or arr[1] ? )
I could use an enum for the array
enum Conf
dowload
parse
end
and then use the values this way
arr[Conf::download] = true
arr[Conf::parse] = true
but it does not seem as easy to use

You're probably looking for a NamedTuple:
arr = {
download: true,
parse: true
}
If the keys are at compile time, this is probably the best.
Otherwise you'd need to use a Hash, which behaves more like an associative array in a dynamic language.

Related

How to empty a multidimensional array?

I wrote an CSV import function. The CSV file gets seperated into columns and rows and is then saved into a multidimensional array.
At one point, I need to set the multidimensional array to Empty, because the following If-condition checks for IsEmpty().
I already tried this:
aMultidimArray = Empty
aMultidimArray = Nothing
ReDim aMultidimArray(0,0)
Erase aMultidimArray
a = Split(sData, sDelimiter)
For Each x In a
'*** Resize and write into multidimensional array
ReDim Preserve aMultidimArray(iFirstDim, iSecondDim)
aMultidimArray(i - 1,iSecondDim) = x
If (i = iFirstDim + 1) Then
i = 0
End If
i = i + 1
Next
'***Empty array here
???
'***
GetDataFromCSV = aMultidimArray
'**** other script
If IsEmpty(GetDataFromCSV) Then
Do stuff
End If
The IsEmpty(GetDataFromCSV) should return true, but I cannot handle it.
It is NOT about clearing the array. It's about getting it uninitialized again. If this is even possible.
As a workaround (or maybe just a better solution) I just called Exit function. As a result the return value is Emptyand the IsEmptycondition will return True.
When in doubt, read the documentation:
IsEmpty returns True if the variable is uninitialized, or is explicitly set to Empty; otherwise, it returns False. False is always returned if expression contains more than one variable.
Since your variable absolutely is initialized, even if you remove all values from the array, why would you expect IsEmpty to return anything but False?
Depending on what you actually want to achieve with your code you could check the dimensions of your array:
If UBound(GetDataFromCSV, 1) = -1 And UBound(GetDataFromCSV, 2) = -1 Then
'array is a 0x0 array
End If
If your array is not zero-sized you probably need to iterate over all fields and check if those are empty.
If you think you need to reset a variable that was defined as an array to Empty I suspect you made a design error somewhere, so I would strongly recommend to go back and fix the design. However, if you absolutely must reset an array variable to Empty for some reason you should be able to do so like this:
ReDim a(2, 5) 'define variable as array
...
Dim a 're-define variable as regular variable; does not clear the value
a = Empty 'clear variable

How to find if item is contained in Dict in Julia

I'm fairly new to Julia and am trying to figure out how to check if the given expression is contained in a Dict I've created.
function parse( expr::Array{Any} )
if expr[1] == #check here if "expr[1]" is in "owl"
return BinopNode(owl[expr[1]], parse( expr[2] ), parse( expr[3] ) )
end
end
owl = Dict(:+ => +, :- => -, :* => *, :/ => /)
I've looked at Julia's documentation and other resources, but can't find any answer to this.
"owl" is the name of my dictionary that I'm trying to check. I want to run the return statement should expr[1] be either "+,-,* or /".
A standard approach to check if some dictionary contains some key would be:
:+ in keys(owl)
or
haskey(owl, :+)
Your solution depends on the fact that you are sure that 0 is not one of the values in the dictionary, which might not be true in general. However, if you want to use such an approach (it is useful when you do not want to perform a lookup in the dictionary twice: once to check if it contains some key, and second time to get the value assigned to the key if it exists) then normally you would use nothing as a sentinel and then perform the check get_return_value !== nothing (note two = here - they are important for the compiler to generate an efficient code). So your code would look like this:
function myparse(expr::Array{Any}, owl) # better pass `owl` as a parameter to the function
v = get(expr[1], owl, nothing)
if v !== nothing
return BinopNode(v, myparse(expr[2]), myparse(expr[3]))
end
# and what do we do if v === nothing?
end
Note that I use myparse name, as parse is a function defined in Base, so we do not want to have a name clash. Finally your myparse is recursive so you should define a second method to this function handling the case when expr is not an Array{Any}.
I feel like an idiot for finding this so fast, but I came up with the following solution: (Willing to hear more efficient answers however)
yes = 1
yes = get(owl,expr[1],0)
if yes != 0
#do return statement here
"yes" should get set equal to 0 if the expression is not found in the dictionary "owl". So a simple != if statement to see if it's zero fixes my problem.

How do you get the Discriminated Union Type from a Case instance?

Given these two Discriminated Unions I'd like to get the DeclaringType from a case instance.
type SingleCaseUnion =
| One
type MultiCaseUnion =
| Two
| Three
An example for each case would be as follows:
getDiscriminatedUnionType One = typeof<SingleCaseUnion> // true
getDiscriminatedUnionType Three = typeof<MultiCaseUnion> // true
My first attempt was to get the case type and get it's base class, this works because in F# a subtype is created for each case.
MultiCaseUnion.Two.GetType().BaseType = typeof<MultiCaseUnion> // true
However, for a single case union this doesn't work because no nested types are created.
SingleCaseUnion.One.GetType().BaseType = typeof<SingleCaseUnion> // false
My second attempt, which aimed to get a more robust solution was to use the FSharp Reflection helpers.
FSharpType.GetUnionCases(unionValue.GetType()).First().DeclaringType
This does work for all cases but it has to generate UnionCaseInfo instances for each case which seems somewhat unnecessary.
Is there Something built in that I may have missed? Something like:
FSharpValue.GetUnionFromCase(SingleCaseUnion.One)
How about
open FSharp.Reflection
type FSharpType =
static member GetUnionType t =
let ownType = t.GetType()
assert FSharpType.IsUnion(ownType)
let baseType = ownType.BaseType
if baseType = typeof<System.Object> then ownType else baseType
Test:
(FSharpType.GetUnionType MultiCaseUnion.Three).Name //MultiCaseUnion
(FSharpType.GetUnionType SingleCaseUnion.One).Name //SingleCaseUnion

Why won't this work as an IIF function, but will as an IF Statement?

The following works:
If 1=1
rdoYes.checked = True
Else
rdoNo.checked = True
End If
However, the following doesn't work:
IIF(1=1, rdoYes.checked = True, rdoNo.checked = True)
Why is this?
Thanks!
It does "work"; it just doesn't do what you want.
IIf in VB.NET is a function (don't use it, ever, by the way), which takes these parameters:
A Boolean condition to check
An Object to return if the condition is True
A different Object to return if the condition is False
In your usage, your condition is 1 = 1; then your two other parameters are rdoYes.Checked = True and rdoNo.Checked = True, both Boolean expressions from the VB compiler's perspective (so, really, they're equivalent to the simpler rdoYes.Checked and rdoNo.Checked).
Remember that in VB.NET, the = sign is only an assignment if it is on its own line. This is how the compiler distinguishes between statements such as x = 5 and If x = 5 Then.
This is not directly related to your question, but you should also be aware that IIf is deprecated and you should almost always favor If instead:
' Let us just suppose it made sense to write this: '
' Notice the If instead of IIf. '
Dim result = If(1 = 1, rdoYes.Checked, rdoNo.Checked)
The IIF() function will return something based on what you enter for the first parameter. Since VB.Net doesn't differ between = as in assignment and = as in comparison (== in many other languages), the second statement is ambiguous.
You can do this with using late binding (delegates in VB.Net):
(Function(c) InlineAssignHelper(c.Checked, true)).Invoke(IIf(1 = 1, chkYes, chkNo))
Private Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
target = value
Return value
End Function
Because IIf takes expressions and returns a result of one of them, and rdoYes.checked = True is not an expression and cannot be returned.
iif doesn't do what you think it does -- the important part is the return from it, so you might be able to do:
iif(1=1, rdoYes, rdoNo).checked = True
(I'm not sure that's valid VB ... it's been more than a decade since I've had to code in it)

Best way to remove all elements from an ActionScript Array?

I'm writing an application in Flex / ActionScript and have a number of class member variables of type Array storing data.
My question is: what's the "best" way to clear out an Array object?
I noticed the ArrayCollection class has a function removeAll() which does this, but the basic Array class does not. Some possibilities I've considered are:
Iterating through the array, calling pop or shift on each element
Setting the array length to 0
Setting the member variable to a "new Array()" or "[]"
I'd say:
myArray = [ ];
That's explicit, short, and makes good use of the VM's garbage collector.
Your first alternative runs a lot of interpreted code to get the same result.
I don't know that the second does what you want; if it does, it's hacky, unclear.
The "new Array()" variant of the third alternative is just wordy, offering no advantage over an array literal. If you also write JS and use JSLint, you'll get yelled at for not using the array literal form.
I'm afraid to say but Warren Young is wrong when he said that setting the myArray = [] cause the garbage collector to pick up the array.
as you have the ability to add a reference to itself within itself, and therefore would never be collected and using up memory, especially if the array has some Sprites in the array, as they too would have the array references them and they too would never be collected.
Sly_cardinal and Richard Szalay are 100% correct. but the length parameter is not needed in Richard's.
To totally clear the array and make sure its collected by garbage then
myArray.splice(0);
myArray = null;
It depends on your context. While using Mr. Young's answer is often the most correct way to do things, it will not always work, especially if you have two variables pointing to the same array:
var foo:Array
var bar:Array
foo = bar = [ 1, 2, 3 ];
bar = [];
trace( foo ); // 1,2,3
On the other hand, if you actually empty the array manually:
var foo:Array
var bar:Array
foo = bar = [ 1, 2, 3 ];
var l:int = bar.length; // get the length FIRST!
// Otherwise bar.length will change
// while you iterate!
for( var i:int = 0; i < l; i++ )
{
bar.shift();
}
trace( foo ); // does not trace anything
If you can modify the array reference, then I would go with Warren's answer. If you need to modify the existing instance, you can also use Array.splice:
var arr : Array = [1, 2, 3, 4, 5];
arr.splice(0, arr.length);
According to this test the best way is to set length = 0

Resources