Creating an Array2D in F# (VS2010 Beta 1) - arrays

Consider the following code fragment in VS2010 Beta 1:
let array = Array2D.zeroCreate 1000 500
This produces an error, namely:
error FS0030: Value restriction. The value 'array' has been inferred to have
generic type val array : '_a [,]
Either define 'array' as a simple data term, make it a function with explicit
arguments or, if you do not intend for it to be generic, add a type annotation.
Can I explicitly set the type (in my case a grid of string)?

You can explicitly specify the type like this:
let array : string [,] = Array2D.zeroCreate 1000 500
For further information on the value restriction you might want to take a look at this F#-Wiki page.

You can also use init to create an array though it might be slower.
let array = Array2D.init 1000 500 (fun _ _ -> "")
Zeroing out an array is usually not seen in functional programming. It's much more common to pass an initilization function to init and just create the array with the values you want.

To create a 2-dimensional array containing empty strings:
let array = Array2D.create 1000 500 ""

Related

How to show elements of array?

I have a small problem. I created a large array.
It looks like this:
var Array = [
["text10", "text11", ["text01", "text02"]],
["text20", "text21", ["text11", "text12"]]
]
If we write this way: Array[0] that shows all the elements.
If we write this way: Array[0][0] that shows "text1".
If we write this way: Array[0][2] that shows
-2 elements
-- 0: "text01"
-- 1: "text02"
.
If we write this way: Array[0][2].count or Array[0][2][0] it will not work
How do I choose each item, I need these elements for the tableView
The problem basically is that your inner array is illegal. Swift arrays must consist of elements of a single type. You have two types of element, String and Array Of String. Swift tries to compensate but the result is that double indexing can’t work, not least because there is no way to know whether a particular element will have a String or an Array in it.
The solution is to rearchitect completely. If your array entries all consist of the same pattern String plus String plus Array of String, then the pattern tells you what to do; that should be a custom struct, not an array at all.
as #matt already answered but I want to add this thing
Why Array[0][2].count or Array[0][2][0] not work
If you Define array
var array = [
["text10", "text11", ["text01", "text02"]],
["text20", "text21", ["text11", "text12"]]
]
And when you type array you can see it's type is [[Any]] However it contains String as well as Array
So When you try to get Array[0][2] Swift does not know that your array at position 2 has another array which can have count
EDIT
What you are asking now is Array of dictionary I suggest you to go with model i.e create struct or class and use it instead of dictionary
Now If you want to create dictionary then
var arrOfDict = ["text10" : ["text01", "text02"] , "text11" : ["text11", "text12"]]
And you can access with key name let arrayatZero = arrOfDict["text10"] as? [String]

Apache-spark: Equal column data structure, different outcome in UDF function

I have two array of columns
arrayColumns1: org.apache.spark.sql.Column = array("col1","col2")
arrayColumns2: org.apache.spark.sql.Column = array("col1","col2")
Both seems equals, but they came from different sources.
arrayColumns1 is from a conversion of Array("col1","col2") to an array, using this function:
def asLitArray[T](xs: Seq[T]) = array(xs map lit: _*)
arrayColumns2 is from writing the textual Array.
Now when I try to use arrayColumns1 as input to an UDF function:
.withColumn("udfFunction",udfFunction(arrayColumns))
where
val udfFunction= udf(
{ xs : Seq[Double] =>
DO_SOMETHING
(output)
}
)
It thorows me this error:
org.apache.spark.sql.AnalysisException: cannot resolve 'UDF(array(col1,col2))' due to data type mismatch: argument 1 requires array<double> type, however, 'array('col1','col2')' is of array<string> type.;;
But when I use arrayColumns2 it works fine. What did I do wrong?
I'm using Spark 2.1 over scala 2.11
It does not make much sense to pass an array of literals to an UDF, because what you want to pass is the name of the columns, not literal values. Your second case fails because you are creating columns of type string (lit("col1") is a literal column with a content of "col1", it does not reference the column col1)
I would to it like this:
def asColArray(xs: Seq[String]) = array((xs.map(x => col(x))): _*)
val arrayColumns = asColArray(Array("col1","col2"))
df.withColumn("udfFunction",udfFunction(arrayColumns))
If you really want to use literal values, you would need to do something like this:
val arrayColumns = asLitArray(Array(1.0,2.0))
But this would give you a constant output of your udf

Is it possible to define the length of a list in F#?

For example, I define a record as:
type a = {b : float; c: int list}
but I already know that this list must be of a predefined size, let's say 2 and if the list is not 2 it would be a different type or error since it is not defined such a type.
Is it possible to define the size of the list as happens in other languages that you must define the size?
Depending on the application this question can be applied to an array.
Maybe you should use an array instead of a list, since an array has a fixed length:
// create an array of length = 2, initialized with zeros.
let cValues : int[] = Array.create 2 0
cValues.IsFixedSize // returns true
EDIT: As others have suggested, a tuple might also be the way to go. For a pair (a tuple of length two), you can access the values using the fst and snd functions.
For a longer tuple, you can use pattern matching as shown below. If the tuple is too long to make this pattern matching approach practical, then you probably need a structure other than an F# tuple. Of course, one major requirement to consider is whether you need to store values of mixed types. A tuple or a record can store a mix of multiple types, whereas an array or list stores values of a single type.
let fourTuple = (5, 10, 2, 3)
let _,_,third,_ = fourTuple
printfn "%d" third // displays "2"
If an array or a tuple won't meet your requirements, then maybe you should use another record like this:
type ListOfC = {c1 : int; c2 : int}
type a' = {b' : float; c' : ListOfC}
Or you could create a new class that would meet your requirements, starting like the script below. Of course, this would probably not be considered idiomatic functional programming style. It's more like OOP.
type ListOfTwo(firstInt : int, secondInt : int) =
member this.First = firstInt
member this.Second = secondInt
let myListOfTwo = ListOfTwo(4, 5)
myListOfTwo.First
type a = {b : float; c : ListOfTwo }

how to get array of properties from array of objects in matlab

I am using an array of objects in my program, and each object has several attributes. I want to be able to extract separate arrays from this array of objects, one array for each attribute.
here is a snippet of the relevant code:
dailyDataMatrix(m,n)=dailyData('',''); %creates an mxn array of dailyData objects
for i=1:m
for j=1:n
dailyDataMatrix(i,j)=dailyData(datainput1, datainput2)%dailyData constructor, sets attributes
end
end
dailyDataMatrix.attribute
But when I try to access a certain attribute as in the code above, say of type string, I get a strange result. Instead of getting an array of strings, I get something else. When I try to print it, rather than printing an array, it prints a series of individual values
ans = 'string1'
ans = 'string2'
...
When I try to call
size(dailyDataMatrix.attribute)
className = class(dailyDataMatrix.attribute)
I get
"error using size: too many input arguments" and
"error using class: The CLASS function must be called from a class constructor."
However, when I write this as
thing=dailyDataMatrix.attribute
className = class(thing)
size(thing)
I get the response
classname = 'double' and size = 1x1.
Why is this not returning an array the same size as dailyDataMatrix? And an aside question is why the two different ways of writing the code above give different results? and how can I get the result that I want?
Thanks,
Paul
You can capture all the outputs using a cell array or using square brackets if the types are same. For regular array when all values are of same type use,
thing=[dailyDataMatrix.attribute];
If the types are different you can use
thing = cell(1,N); % N is the number of elements in dailyDataMatrix
[thing{:}] = dailyDataMatrix.attribute;

Initialize Array to Blank custom type OCAML

ive set up a custom data type
type vector = {a:float;b:float};
and i want to Initialize an array of type vector but containing nothing, just an empty array of length x.
the following
let vecarr = Array.create !max_seq_length {a=0.0;b=0.0}
makes the array init to {a=0;b=0} , and leaving that as blank gives me errors. Is what im trying to do even possible?
You can not have an uninitialized array in OCaml. But look at it this way: you will never have a hard-to-reproduce bug in your program caused by uninitialized values.
If the values you eventually want to place in your array are not available yet, maybe you are creating the array too early? Consider using Array.init to create it at the exact moment the necessary inputs are available, without having to create it earlier and leaving it temporarily uninitialized.
The function Array.init takes in argument a function that it uses to compute the initial value of each cell.
How can you have nothing? When you retrieve an element of the newly-initialized array, you must get something, right? What do you expect to get?
If you want to be able to express the ability of a value to be either invalid or some value of some type, then you could use the option type, whose values are either None, or Some value:
let vecarr : vector option array = Array.create !max_seq_length None
match vecarr.(42) with
None -> doSomething
| Some x -> doSomethingElse
You can initialize and 'a array by using an empty array, i.e., [||]. Executing:
let a = [||];;
evaluates to:
val a : 'a array = [||]
which you can then append to. It has length 0, so you can't set anything, but for academic purposes, this can be helpful.

Resources