6

I have 2 arrays. Array 1 is a string array that contains the names of types.

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 contents look like this:

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

My problem is that all the values in Array 2 are strings, and I want them to be of the types in Array 1. Is there a way that I can type cast the strings in Array 2 using the strings in Array 1?

1
  • 2
    First, obviously those are SQL column types and not .NET types. Second, you cannot really have an array of different types. Third, that's what type providers are for, and SQLProvider has a nifty .Mapto method that does this. You should be storing this in an array of records, and your life would be much easier. Commented Oct 12, 2016 at 8:49

3 Answers 3

6

As @s952163 points out, it looks like you're attempting to read data from a database, in which case there are better options available than trying to do it yourself. Still, just to sketch out a possible solution if taking the OP at face value, here's one way to go about it.

Since the types listed aren't .NET types, perhaps it's better to define a custom type to hold such values:

open System

type DbType = NVarChar of string | DT of DateTime

You can add more cases to DbType if you'd like.

Using active patterns, 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

The use of active patterns isn't strictly necessary, but I thought it enabled me to decompose the problem in a good way.

Now you can declare a list of types and one of values, zip 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 have the type string list. In the OP, they were (string * string * string * string) list, which I assume was a mistake.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes it was a mistake. Thank you for the correction. also thank you for the comment. It'll help someone. I thought it'd help me but I then realized I was asking the wrong the questions.
5

Actually you have a few issues here.

Commas create Tuples your code

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

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

If you want to create a string list you would have to use a semicolon ;.

Now if you know that your code has always the same exact 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 includes rows of different sizes and you want convert from or to SQL data types than maybe an approach using Discriminate Unions could be helpful.

type SQLDataType =
   | VarChar of string
   | Date of DateTime

type Row = SQLDataType list
type Rows = RowItem list

The usage then would be like this

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

finally you should write then some conversion functions that convert that from and to your SQL data

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

I hope this helps.

1 Comment

Thank you for the comment. It'll help someone. I thought it'd help me but I then realized I was asking the wrong the questions.
0

This is a bit of a low-level solution as it's not very obvious where all this is headed, but if all that is you need is for your strings to be of the db types, then T-SQL has Cast and Convert and also this for you. So you can just say CAST ("1991-04-19T00:00:00" AS date).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.