I have the following tabular data:
Raw data:
Description
String A Q1FY18
String B Q1FY18, String B Q2FY18
String C Q4FY17, String C Q1FY18, String D Q2FY18
String E Q2FY18
I would like to split this column into multiple columns. The target data frame would look like this:
Desired output:
Description Period
String A Q1FY18
String B Q1FY18
String B Q2FY18
String C Q4FY17
String C Q1FY18
String D Q2FY18
String E Q2FY18
What comes to mind is that the original column is comma delimited, so there must be a way to create new columns by splitting the strings using the comma as the delimiter. This step would look something like this:
First step
Description Period1 Period2
String A Q1FY18
String B Q1FY18 Q2FY18
String C Q4FY17 Q1FY18
String E Q1FY18 Q2FY18
The next step would be to collapse the table to get the desired output. It would be easier if I could use other tools for data manipulation such as R or Python, but those are not an option in this case due to end-user limitations. How would you go about transforming the raw data to get to the desired output? Is there some way to split the raw data using the comma as the delimiter and having access automatically determine the number of new columns it should create? I would appreciate your help!
You could try something like this:
Dim strArray() As String
strTest = "String B Q1FY18, String B Q2FY18"
strArray = Split(strTest, ",")
For intCount = LBound(strArray) To UBound(strArray)
Debug.Print Trim(strArray(intCount))
Next
Related
I have string column in my hive table and I would the output to be in the following way:
Column A Column B
ddjj3332 jjn32212 334334 (3332, 32212, 334334)
I have tried to do regex replace in the string to remove the alphabets. But I am unable to convert it into an array.
Let me know if this is possible.
You can use split to make an array after you perform the replace:
split(regexp_replace(column_a, '[^0-9 ]', ''), ' ')
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?
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.
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.
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).
I want to convert an array to string in hive. I want to collect_set array values to convert to string without [[""]].
select actor, collect_set(date) as grpdate from actor_table group by actor;
so that [["2016-07-01", "2016-07-02"]] would become 2016-07-01, 2016-07-02
Use concat_ws(string delimiter, array<string>) function to concatenate array:
select actor, concat_ws(',',collect_set(date)) as grpdate from actor_table group by actor;
If the date field is not string, then convert it to string:
concat_ws(',',collect_set(cast(date as string)))
Read also this answer about alternative ways if you already have an array (of int) and do not want to explode it to convert element type to string: How to concatenate the elements of int array to string in Hive
Sometimes, you may need a JSON formatted list, so you can simply use:
SELECT CAST(COLLECT_SET(date) AS STRING) AS dates FROM actor_table
PS: I needed this but found only your question about array to string conversion.
I am new to visual basic at college and I am using the purely console-based version of the software. I have been set a task to, without using an array, allow the user to input 5 student names and their respective test scores and store them in 10 separate variables, using a loop. The program must then output the highest test score and the student it is assigned to.
I know that I have to use a for loop for this and have been trying to concatenate the i (assuming for i = 1 to 5) with variable names and then using console.readline to assign the variables to a value. This has been to no avail so far and I don't know what to do. Any help is appreciated.
Thanks,
George
without using an array
That's quite odd. I'll assume that also means any collection.
have been trying to concatenate the i (assuming for i = 1 to 5) with variable names.
There really isn't a good way to do that, not without some kind of code generation. You could use fields and reflection, but thats way, way out of scope most likely.
The easiest thing to do then, is just use If on the loop variable and assign the correct variable based on what i is.
Dim name1 As String, name2 As String, name3 As String, name4 As String, name5 As String
Dim score1 As Integer, score2 As Integer, score3 As Integer, score4 As Integer, score5 As Integer
For i As Integer = 1 To 5
Console.Write("Name: ")
Dim name = Console.ReadLine()
Console.Write("Score: ")
'TODO: Error checking
Dim score = Int32.Parse(Console.ReadLine())
If i = 1 Then
name1 = name
score1 = score
ElseIf i = 2 Then
name2 = name
score2 = score
End If
'Etc
Next
'Calculate check the variables for the highest score
It's crude, but it meets the criteria. If a Dictionary or List were allowed, that makes things much simpler:
Dim people As New Dictionary(Of String, Integer)
For i As Integer = 1 To 5
Console.Write("Name: ")
Dim name = Console.ReadLine()
Console.Write("Score: ")
'TODO: Error checking
Dim score = Int32.Parse(Console.ReadLine())
people.Add(name, score)
Next
'Calculate the highest score on the dictionary
If the requirement is that you must use five separate variables because you are not allowed to use an enumerable list of any kind, then I would recommend creating two methods that allow you to get and set the values by index:
Private _name0 As String
Private _name1 As String
Private _name2 As String
Private _name3 As String
Private _name4 As String
Private Function GetName(index As Integer) As String
Select Case index
Case 0
Return _name0
Case 1
Return _name1
Case 2
Return _name2
Case 3
Return _name3
Case 4
Return _name4
End Select
Throw New ArgumentOutOfRangeException()
End Function
Private Sub SetName(index As Integer, name As String)
Select Case index
Case 0
_name0 = name
Case 1
_name1 = name
Case 2
_name2 = name
Case 3
_name3 = name
Case 4
_name4 = name
End Select
Throw New ArgumentOutOfRangeException()
End Sub
Then you could do the same for the scores. Since .NET is not a dynamically typed language, it doesn't easily support accessing variables by a dynamically built string name. While it's technically feasible to accomplish something like that via Reflection, I doubt that's the intended purpose of the exercise.
I need to validate in my query if the value of a string (the first part) is equal to a definited value, for instance:
String
----------
F11-EDEDED
F1-SAFSDA
F455-ADADD
F11-ASDA-FAFA
And validate when the string is F11, i was searching something like split on vba, but i can't find it.
Im working with :
Case when ("splitted string") =F11 then X)
Use a Left() and Charindex() to grab the beginning of your strings.
Declare #str varchar(100)='F11-ASDA-FAFA'
Select #str,Case When left(#str,charindex('-',#str)-1)='F11' Then 1 Else 0 End