F # Fill Type of String Array

I have 2 arrays. Array 1 is a string array that contains type names.

So, the contents of array 1 looks like this:

["nvarchar";"nvarchar";"date";"nvarchar"] //these are all strings 

Array 2 is another array of strings, and the content is as follows:

 ["Jackson";"Sentzke";"1991-04-19T00:00:00";"Jackson Sentske"] 

My problem is that all values ​​in array 2 are strings, and I want them to be from the types in array 1. Is there a way I can print strings in array 2 using strings in array 1?

+6
source share
3 answers

As @ s952163 points out, it looks like you're trying to read data from a database, in which case there are better options than trying to do it yourself. However, just to outline a possible solution, if you take the OP at face value, here is one way to do this.

Since the types listed are not .NET types, it might be better to define a native type to store these values:

 open System type DbType = NVarChar of string | DT of DateTime 

You can add a few cases to DbType if you want.

Using active templates , you can write a function to convert a single candidate:

 // string * string -> string option let (|NVarChar|_|) = function | "nvarchar", (x : string) -> Some x | _ -> None // string * string -> DateTime option let (|DT|_|) (typeHint, value) = match (typeHint, DateTime.TryParse value) with | "date", (true, dt) -> Some dt | _ -> None // string * string -> DbType option let convertPair = function | NVarChar x -> Some (NVarChar x) | DT x -> Some (DT x) | _ -> None 

Using active templates is not strictly necessary, but I thought that it allowed me to efficiently decompose the problem.

Now you can declare a list of types and one of the values, pin them together to get a list of interpreted values:

 > let types = ["nvarchar"; "nvarchar"; "date"; "nvarchar"];; val types : string list = ["nvarchar"; "nvarchar"; "date"; "nvarchar"] > let values = ["Jackson"; "Sentzke"; "1991-04-19T00:00:00"; "Jackson Sentske"];; val values : string list = ["Jackson"; "Sentzke"; "1991-04-19T00:00:00"; "Jackson Sentske"] > let converted = List.zip types values |> List.choose convertPair;; val converted : DbType list = [NVarChar "Jackson"; NVarChar "Sentzke"; DT 19.04.1991 00:00:00; NVarChar "Jackson Sentske"] 

Note that both types and values are of type string list . In the OP they were (string * string * string * string) list , which I suppose was a mistake.

+6
source

You actually have a few problems.

Commas create tuples in your code.

 ["nvarchar","nvarchar","date","nvarchar"] 

not a string list , but (string * string * string * string) list

If you want to create a string list , you will need to use a semicolon ; .

Now, if you know that your code always has the exact same number of tuple elements with the exact types you want, than you could do it like this

 type RowItems = string * string * DateTime * string type Rows = RowItem list 

Now, if your problem involves strings of different sizes, and you want to convert from or to SQL data types, than the Discriminate Unions approach can be useful.

 type SQLDataType = | VarChar of string | Date of DateTime type Row = SQLDataType list type Rows = RowItem list 

Then use will be like this:

 let row = [ VarChar "Jackson"; VarChar "Sentzke"; Date DateTime.parse("1991-04-19T00:00:00"); VarChar "Jackson Sentske" ] 

Finally, you must write some conversion functions that convert data from and to your SQL data.

 let fromSQL (s:string) : SQLDataType = ... let toSQL (s:SQLDataType) : string = ... 

Hope this helps.

+5
source

This is a slightly low-level solution, since it is not very obvious where all this is directed, but if all you need is that your rows are of db types, then T-SQL has Include and Convert , as well as this one for you. So you can just say CAST ("1991-04-19T00:00:00" AS date) .

+1
source

All Articles