I often use the inputdialog to execute a command using:
let n = confirm({msg} [, {choices} [, {default} [, {type}]]])
p.e. search numbers
if n == 1 --> p.e. do search of all numbers with '.,'
if n == 2 --> p.e. do search of all exponential numbers
if n == 3 --> p.e. do search of all numbers with 3 digits
etc
but with this method I can only choose one argument.
Is there a way in Vim where you can chose multiple arguments together in an inputdialog?
You could use input() to prompt the user to input a string, and then inspect the returned list:
let string = input( {msg}, {choices}, ... )
For example, the user could enter 1,2,3, and you can do a text comparison of this string:
if ( string =~ 1 )
" do something
endif
if ( string =~ 2 )
" do something
endif
if ( string =~ 3 )
" do something
endif
A more sophisticated approach (e.g. if there are more than 9 options) might be to split the string into a list:
let choice_list = split( string, ',' )
for choice in choice_list
if choice == 1
" do something
endif
if choice == 2
" do something
endif
if choice == 3
" do something
endif
endfor
Since the returned string could be anything the user decides to enter, you might want to add some sanity checks that the string is indeed a list of integers.
A workaround, use input() function, let the user to choose multiple options and split them into a list to process them. An example:
Add next function to vimrc or similar file:
func My_search()
let my_grouped_opts = input ( "1.- Search one\n2.- Search two\n3.- Search three\n" )
let my_list_opts = split( my_grouped_opts, '.\zs' )
for opt in my_list_opts
echo "Option number " opt " selected"
endfor
endfunction
Call it:
:call My_search()
There will appear your options:
1.- Search one
2.- Search two
3.- Search three
Select them like:
23
And the function will split them into a list.
Related
I have a column which I am splitting in Snowflake.
The format is as follows:
I have been using split_to_table(A, ',') inside of my query but as you can probably tell this uncorrectly also splits the Scooter > Sprinting, Jogging and Walking record.
Perhaps having the delimiter only work if there is no spaced on either side of it? As I cannot see a different condition that could work.
I have been researching online but haven't found a suitable work around yet, is there anyone that encountered a similar problem in the past?
Thanks
This is a custom rule for the split to table, so we can use a UDTF to apply a custom rule:
create or replace function split_to_table2(STR string, DELIM string, ROW_MUST_CONTAIN string)
returns table (VALUE string)
language javascript
strict immutable
as
$$
{
initialize: function (argumentInfo, context) {
},
processRow: function (row, rowWriter, context) {
var buffer = "";
var i;
const s = row.STR.split(row.DELIM);
for(i=0; i<s.length-1; i++) {
buffer += s[i];
if(s[i+1].includes(row.ROW_MUST_CONTAIN)) {
rowWriter.writeRow({VALUE: buffer});
buffer = "";
} else {
buffer += row.DELIM
}
}
rowWriter.writeRow({VALUE: s[i]})
},
}
$$;
select VALUE from
table(split_to_table2('Car > Bike,Bike > Scooter,Scooter > Sprinting, Jogging and Walking,Walking > Flying', ',', '>'))
;
Output:
VALUE
Car > Bike
Bike > Scooter
Scooter > Sprinting, Jogging and Walking
Walking > Flying
This UDTF adds one more parameter than the two in the build in table function split_to_table. The third parameter, ROW_MUST_CONTAIN is the string a row must contain. It splits the string on DELIM, but if it does not have the ROW_MUST_CONTAIN string, it concatenates the strings to form a complete string for a row. In this case we just specify , for the delimiter and > for ROW_MUST_CONTAIN.
We can get a little clever with regexp_replace by replacing the actual delimiters with something else before the table split. I am using double pipes '||' but you can change that to something else. The '\|\|\\1' trick is called back-referencing that allows us to include the captured group (\\1) as part of replacement (\|\|)
set str='car>bike,bike>car,truck, and jeep,horse>cat,truck>car,truck, and jeep';
select $str, *
from table(split_to_table(regexp_replace($str,',([^>,]+>)','\|\|\\1'),'||'))
Yes, you are right. The only pattern, which I can see, is the one with the whitespace after the comma.
It's a small workaround but we can make use of this pattern. In below code I am replacing such commas, where we do have whitespaces afterwards. Then I am applying split to table function and I am converting the previous replacement back.
It's not super pretty and would crash if your string contains "my_replacement" or any other new pattern, but its working for me:
select replace(t.value, 'my_replacement', ', ')
from table(
split_to_table(replace('Car > Bike,Bike > Scooter,Scooter > Sprinting, Jogging and Walking,Walking > Flying', ', ', 'my_replacement'),',')) t
Hey I am working in kotlin. I have one string in which I want to split into list from there where I should provide character. I'll explain in details
For example 1
val string = "Birth Control"
val searchText = "n"
Output
["Birth Co", "trol"]
For example 2
val string = "Bladder Infection"
val searchText = "i"
Actual Output
["Bladder ", "nfect", "on"]
Expect Output
["Bladder ", "nfection"]
I tried some code but example 1 is working fine but example 2 is not because I only want to split first occurrence.
val splitList = title?.split(searchText, ignoreCase = true)?.toMutableList()
splitList?.remove(searchText)
Can someone guide me how to solve this idiomatic way. Thanks
You miss the limit option of the split function. If you give it a value of 2 the result list will have a maximum of 2 entries:
val result = "Bladder Infection".split("i", ignoreCase = true, limit = 2)
I rather have this ugly way of building a string from a list as:
val input = listOf("[A,B]", "[C,D]")
val builder = StringBuilder()
builder.append("Serialized('IDs((")
for (pt in input) {
builder.append(pt[0] + " " + pt[1])
builder.append(", ")
}
builder.append("))')")
The problem is that it adds a comma after the last element and if I want to avoid that I need to add another if check in the loop for the last element.
I wonder if there is a more concise way of doing this in kotlin?
EDIT
End result should be something like:
Serialized('IDs((A B,C D))')
In Kotlin you can use joinToString for this kind of use case (it deals with inserting the separator only between elements).
It is very versatile because it allows to specify a transform function for each element (in addition to the more classic separator, prefix, postfix). This makes it equivalent to mapping all elements to strings and then joining them together, but in one single call.
If input really is a List<List<String>> like you mention in the title and you assume in your loop, you can use:
input.joinToString(
prefix = "Serialized('IDs((",
postfix = "))')",
separator = ", ",
) { (x, y) -> "$x $y" }
Note that the syntax with (x, y) is a destructuring syntax that automatically gets the first and second element of the lists inside your list (parentheses are important).
If your input is in fact a List<String> as in listOf("[A,B]", "[C,D]") that you wrote at the top of your code, you can instead use:
input.joinToString(
prefix = "Serialized('IDs((",
postfix = "))')",
separator = ", ",
) { it.removeSurrounding("[", "]").replace(",", " ") }
val input = listOf("[A,B]", "[C,D]")
val result =
"Serialized('IDs((" +
input.joinToString(",") { it.removeSurrounding("[", "]").replace(",", " ") } +
"))')"
println(result) // Output: Serialized('IDs((A B,C D))')
Kotlin provides an extension function [joinToString][1] (in Iterable) for this type of purpose.
input.joinToString(",", "Serialized('IDs((", "))')")
This will correctly add the separator.
code:
case when length(neutral)>0 then regexp_extract(neutral, '(.*#)', 0) else '' end as neutral
The above query returns the output value with # symbol, for example if the input is 1234#gmail.com, then the output is 1234#. how to remove the # symbol using the above query. And the resulting output should be evaluated for numbers, if it contains any non-numeric characters it should get rejected.
sample input:1234#gmail.com output: 1234
sample input:123adc#gmail.com output: null
You could phrase the regex as ^[^#]+, which would match all characters in the email address up to, but not including, the # character:
REGEXP_EXTRACT(neutral, '^[^#]+', 0) AS neutral
Note that this approach is also clean and frees us from having to use the bulky CASE expression.
Try this code:
val pattern = """([0-9]+)#([a-zA-Z0-9]+.[a-z]+)""".r
val correctEmail = "1234#gmail.com"
val wrongEmail = "1234abcd#gmail.com"
def parseEmail(email: String): Option[String] =
email match {
case pattern(id, domain) => Some(id)
case _ => None
}
println(parseEmail(correctEmail)) // prints Some(1234)
println(parseEmail(wrongEmail)) // prints None
Also, it is more idiomatic to use Options instead of null
I'm learning Elm and trying to understand how to append a string to all items in a list, but at the end of each entry rather than the beginning. Sorry for the n00b question but I've read through all the docs/examples around List.map, String (.append, .join) and can't seem to find an answer.
e.g.
--create username list
usernames = ["Dave", "Simon", "Sally", "Joe"]
--create confirmExit function
confirmExit name = String.append " has left the room" name
--apply confirmExit function to all items in username list
List.map (\x -> confirmExit x) usernames
Gives me:
["has leftDave","has leftSimon","has leftSally","has leftJoe"] : List String
But how would I make it so that it returned:
["Dave has left","Simon has left","Sally has left","Joe has left"] : List String
Is there an equivalent of .append to add to the end instead of the beginning? Please?!
You just have the parameters reversed, try:
confirmExit name = String.append name " has left the room"
From the docs:
append : String -> String -> String
Append two strings. You can also
use the (++) operator to do this.
append "butter" "fly" == "butterfly"
So you could also use:
confirmExit name = name ++ " has left the room"
Which is possibly a bit more readable