I currently have an array containing x amount of strings and am looking to append all of these entries to a string in OCaml.
I know that the way to append a string to another in OCaml is by using
let a ="Hello"
let b= "Blah Blah " ^ a
However I would like to do this using all entries in my array. Then continue the string after appending the full array. Something similar to this:
let myArray = Array.make stages "Some text"
let myString = "I'm looking to append "^(ALL ENTRIES IN ARRAY)^" to this string"
If you had a list of strings rather than array then String.concat will do the trick. So if you have array you could convert the array to list and then apply String.concat as in:
String.concat " " (Array.to_list str_arr)
But if you don't want to convert it to a list you could use fold_left as in:
Array.fold_left (fun x y -> x ^ y ^ " ") "" str_arr
Notice that fold_left appends a space to every string in the array including the last one. String.concat is better; it uses the filler only between the strings
Related
I was reading over some resources about Swift 5's String Interpolation and was trying it out in a Playground. I successfully combined two separate Strings but I am confused about how to combine an Array of Strings.
Here's what I did ...
String(stringInterpolation: {
let name = String()
var combo = String.StringInterpolation(literalCapacity: 7, interpolationCount: 1)
combo.appendLiteral("Sting One, ")
combo.appendInterpolation(name)
combo.appendLiteral("String Two")
print(combo)
return combo
}())
How would you do something like this with an Array of Strings?
It’s unclear what this is supposed to have to do with interpolation. Perhaps there’s a misunderstanding of what string interpolation is? If the goal is to join an array of strings into a single comma-separated string, just go ahead and join the array of strings into a single string:
let arr = ["Manny", "Moe", "Jack"]
let s = arr.joined(separator: ", ")
s // "Manny, Moe, Jack”
If the point is that the array element type is unknown but is string-representable, map thru String(describing:) as you go:
let arr = [1,2,3]
let s = arr.map{String(describing:$0)}.joined(separator: ", ")
s // "1, 2, 3”
I have a problem with performance in large arrays (50k each). What would be the fastest way of finding a string that starts with another string given two arrays? I'm have tried different things, but the code below seems to be as good as I can get it.
let findFile (f:string, p:string, pc:string, pcn:string) =
f.StartsWith(p + "-" + pc) ||
f.StartsWith(p + "_" + pc) ||
f.StartsWith(p + "-" + pcn) ||
f.StartsWith(p + "_" + pcn)
products
|> Array.Parallel.map (fun i p ->
allFiles |> Array.Parallel.map (fun f ->
if findFile (f.Filename, p.Style, p.ColorCode, p.ColorName)
then {p with Filename = f.Filename }
else p
))
Thank you in advance.
First I would recommend to sanitize the filenames by splitting the two parts and if possible removing the rest:
Split the filenames by the '-'or '_' character so you compare tuples of (style * color) instead of strings twice. Also if at all possible, differentiate between when using color code from color name and separate into 2 arrays.
Now you have 2 options: use a Dictionary or sort the values
Dictionary: take the longer list and put it in a dictionary. Scan the shorter list looking for the values. Dictionaries use hash tables which make them very efficient and comparisons are also very fast. This requires that you use as a key only the style and color code/name leaving the rest of the string out.
The solution could look like this:
let dict () =
let dict = new Dictionary<_, _>()
allFiles |> Seq.iter (fun f -> f.Filename.Split '-' |> fun a -> dict.Add((a.[0], a.[1]), f) )
products
|> Array.Parallel.map (fun p ->
let vRef = ref { Filename = "" }
if dict.TryGetValue((p.Style, p.ColorCode) , vRef)
then {p with Filename = (!vRef).Filename }
else p
)
If that is not possible consider then:
Sorting both lists: products and filenames. Scan both ordered lists simultaneously with an index each only advancing the lower value each time.
One more thing:
If you still want to do string comparisons you should consider using compiled Regex which are very efficient. Your regex could be something like: ^code[-_](red|FF0000) which would match any of the 4 values:
code-red
code_red
code-FF0000
code_FF0000
This is how you use compiled Regex:
let regex = new Regex(sprintf "^%s[-_](%s|%s)" p.Style p.ColorCode p.ColorName, RegexOptions.Singleline + RegexOptions.Compiled)
for i in 1..30 do
if regex.IsMatch(sprintf "code-%d" i) then printfn "%A" i
I have an Array like this.
scala> var x=Array("a","x,y","b")
x: Array[String] = Array(a, x,y, b)
How do I change the separator comma in array to a :. And finally convert it to string like this.
String = "a:x,y:b"
My aim is to change the comma(separators only) to other separator(say,:), so that i can ignore the comma inside second element i.e, x,y. and later split the string using : as a delimiter
Your question is unclear, but I'll take a shot.
To go from:
val x = Array("a","x,y","b")
to
"a:x,y:b"
You can use mkString:
x.mkString(":")
I have a string in F#:
let name = "Someone"
I also have an array of strings:
let mutable arraysOfNames : string[] = [||]
I want to add the string name to the array arrayOfNames. How do I do that? It doesn't have to be an array, it can be a Sequence or any other collection that I can check then if it is empty or not.
It is not possible to add an item to a zero-length array. All you can do is create a new array that holds the item. The currently accepted answer, using Array.append, does not modify the input arrays; rather, it creates a new array that contains the elements of both input arrays. If you repeatedly call append to add a single element to an array, you will be using memory extremely inefficiently.
Instead, in f#, it makes much more sense to use F#'s list type, or, for some applications, ResizeArray<'T> (which is f#'s name for the standard .NET List). If you actually need the items in an array (for example, because you have to pass them to a method whose parameter is an array type), then do as Steve suggests in his comment. Once you have built up the collection, call List.toArray or Array.ofList if you're using an F# list, or call the ToArray() instance method if you're using a ResizeArray.
Example 1:
let mutable listOfNames : string list = []
listOfNames <- "Alice" :: listOfNames
listOfNames <- "Bob" :: listOfNames
//...
let names = listOfNames |> List.toArray
Example 2:
let resizeArrayOfNames = ResizeArray<string>()
resizeArrayOfNames.Add "Alice"
resizeArrayOfNames.Add "Bob"
let names = resizeArrayOfNames.ToArray()
Note that in the first example, you'll get the names in reverse order; if you need them in the same order in which they were added, you'd need
let names = listOfNames |> List.rev |> List.toArray
For any Seq which is IEnumerable<T> alias in F# you can write this function:
let addToSequence aseq elm = Seq.append aseq <| Seq.singleton elm
And use it this way:
let withSomeone = addToSequence [||] "Someone"
You can use Seq.toArray or Seq.toList after you get a result sequence
Take a look at Array.append.
// Signature: Array.append : 'T [] -> 'T [] -> 'T []
// Usage: Array.append array1 array2
So in your case, you can use it like this:
let name = "someone"
let mutable arrayOfNames = Array.append [|"test"; "abc"|] [|name|]
printfn "%A" arrayOfNames
//[|"test"; "abc"; "someone"|]
So you simply need to transform your string into an array (by using [|string|]). Since Array contains the append function, you can append a string this way to an array.
You can use Array.append with mutable arrays:
let mutable my_array = [||]
for i in 0 .. array_size do
my_array <- [|i|] |> Array.append my_array
// my_array <- Array.append my_array [|i|]
printfn "my array is: %A" my_array
I have a string 'ADSL'. I want to find this string in an array of strings char('PSTN,ADSL','ADSL,VDSL','FTTH,VDSL')
when i run this command
strmatch('ADSL',char('PSTN,ADSL','ADSL,VDSL','FTTH,VDSL'));
the output is 2
But I expect the output as [1 2]
strmatch only gives positive result if the search string appears at the begining of row.
How can I find the search string if it occurs anywhere in the row?
Given the following input:
array = {'PSTN,ADSL', 'ADSL,VDSL', 'FTTH,VDSL'};
str = 'ADSL';
We find the starting position of each string match using:
>> pos = strfind(array, str)
pos =
[6] [1] []
or
>> pos = regexp(array, str)
pos =
[6] [1] []
We can then find the indices of matching strings using:
>> matches = find(~cellfun(#isempty,pos))
matches =
1 2
For an array of strings, it's better to use a cell array. That way strings can be of differnet lengths (and regexp can be applied on all cells at once):
cellArray = {'PSTN,ADSL','ADSL,VDSL','FTTH,VDSL'};
str = 'ADSL';
Then:
result = find(~cellfun('isempty', regexp(cellArray, str)));
will give what you want.
If you really have a char array as in your example,
array = char('PSTN,ADSL','ADSL,VDSL','FTTH,VDSL');
you can convert to a cell array (with cellstr) and apply the above:
result = find(~cellfun('isempty', regexp(cellstr(array), str)));
i would use strfind
a=strfind(cellstr(char('PSTN,ADSL','ADSL,VDSL','FTTH,VDSL')),'ADSL');
in this case will be a three by one cell array containing the index where you string starts at in the corresponding string