if var in/contains comma-separated list/array

Post a reply


In an effort to prevent automatic submissions, we require that you type the text displayed into the field underneath.
Smilies
:D :) ;) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :!: :?: :idea: :| :mrgreen: :geek: :ugeek: :arrow: :angel: :clap: :crazy: :eh: :lolno: :problem: :shh: :shifty: :sick: :silent: :think: :thumbup: :thumbdown: :salute: :wave: :wtf: :yawn: :facepalm: :bravo: :dance: :beard: :morebeard: :xmas: :HeHe: :trollface: :cookie: :rainbow: :monkeysee: :monkeysay: :happybday: :headwall: :offtopic: :superhappy: :terms: :beer:
View more smilies

BBCode is ON
[img] is OFF
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: if var in/contains comma-separated list/array

Re: if var in/contains comma-separated list/array

Post by guest3456 » 15 Feb 2018, 09:34

jeeswg wrote:- Out of interest. If in/contains became functions, what should they be called.


they shouldn't be functions, so the question is irrelevant. they are much nicer as operators which can handle multiple operand types :

Code: [Select all] [Expand]GeSHi © Codebox Plus



actually not sure how the arry/obj should be handled, since i dont believe they are two distinct types, but rather both are just objects. becuase in the example above, the array is testing for the value, but the obj is testing for the key

for string types, it could essentially replicate InStr() instead of only operating on comma separated strings, which would eliminate the need for contains. i dont think comma separated strings should be standard practice

Re: if var in/contains comma-separated list/array

Post by jeeswg » 15 Feb 2018, 09:11

- Out of interest. If in/contains became functions, what should they be called.
in: In / StrIn (too much like InStr) / StrExact / StrWhole / something else?
contains: Contains / StrContains / something else?
- Does 'Exact' imply case sensitive, or not? Does it imply whole match, or not? Thanks.

Re: if var in/contains comma-separated list/array

Post by jeeswg » 01 Feb 2018, 11:52

Also, I wanted to point out the benefits of the general principle of literal text to arrays, which I use regularly.

Code: [Select all] [Expand]GeSHi © Codebox Plus

Re: if var in/contains comma-separated list/array

Post by nnnik » 01 Feb 2018, 11:37

You're the only one that has this problem because you got used to comma separated lists in the first place.
Comma separated lists have no real future in AHK.

Re: if var in/contains comma-separated list/array

Post by jeeswg » 01 Feb 2018, 11:32

- I find comma-separated lists easier to read.
- Some arguments against ["abc", "def", "ghi"]:
(a) harder to type / easier to typo (try the typing challenge above)
(b) takes more horizontal real estate
(c) you have to convert comma-separated lists copied from elsewhere
(d) harder to visually inspect (especially when special characters or quotes/apostrophes are used)
(e) more time-consuming to edit
- Do I really want to 'objectify' something like this. JEE_MX acts like the 'in' function.

Code: [Select all]GeSHi © Codebox Plus

if JEE_MX(vItem, "svm,svb,svy")
if JEE_MX(vItem, "setvid,sevi,svi,sv,svm,svb,svy")
if JEE_MX(vItem, "setbox,sebo")
if JEE_MX(vItem, "seturl,seur")
if JEE_MX(vItem, "setpag,sepa")
if JEE_MX(vItem, "sebl")
if JEE_MX(vItem, "ytpa,ypa")

- My plan at present is this, 7 functions:
MC,MX (contains/in) (where a comma delimiter is assumed, 2 parameters only).
StrContains/StrExact (or another name)/StrStarts/StrEnds (where you can specify the delimiter, and other options).
StrMatch (for anything else, which also acts as 'StrCompare', e.g. get items that 'match' the </<= comparison criteria).
- I don't currently use a dedicated comma-separated list to object function, because I have these functions. Simply creating an array via StrSplit, on one line, isn't too bad, but if had to use that regularly within functions or with 'contains', that would be more of a problem. Also, generally, I don't like using functions within functions, because of readability issues.
- I have been genuinely undecided re. having a 'contains' function that did or did not assume delimiting by comma by default. It was a perfect clash between convenience and conventionality. I knew that I had to have a conventional function, but in the end, I decided to have two functions, to do both.
- For me, the best compromise for AutoHotkey, would be StrContains/StrXXX functions where you could specify "D,". So StrContains/StrExact/StrMatch. And I think that StrStarts/StrEnds are absolutely worthwhile, and envisaged them shortly after I started using AutoHotkey.
- If I had to submit a quick script to the forum, StrSplit would be acceptable, so I don't mind AutoHotkey not having comma/pipe-separated list to array functions. And although I haven't advocated for such functions to be added to AutoHotkey, I think the idea of two such functions is absolutely sound. Comma-separated list to array, so CSLA, or CSL or CSA are possibilities, but then 'new CSA', could be new case-sensitive array. I appreciate that those names aren't necessarily an obvious fit with AutoHotkey.
- Re. delimited lists to arrays. I think there should be separate functions for the first 65535 Unicode characters. Actually, no I don't. Just comma and pipe. Pipes are useful when your list contains commas. Purely out of interest, are there other common delimiter characters?
- I don't find it a good argument to say that a feature is unique therefore shouldn't exist. Every programming language has unique features.
- I don't buy the argument re. one style is more widespread. If people only know AutoHotkey, then anything in AutoHotkey is perfectly normal. If people know other programming languages, they know all sorts of features unique to different languages. Something like the CSL function proposal would be extremely useful in any programming language.

Re: if var in/contains comma-separated list/array

Post by guest3456 » 01 Feb 2018, 09:56

just me wrote: It might not be 'convenient' when writing scripts, but it is 'convenient' for me when 'parsing' scripts whith my built-in parser, my eyes.


:clap:

90% of programming is reading and editing code. the initial writing is of so little importance that it hardly matters. this is why style guidelines, indentation, etc is so important.

Re: if var in/contains comma-separated list/array

Post by just me » 01 Feb 2018, 04:18

@coffee:
To be clear, I mentioned StrSplit() as an example for a string function which already excepts string arrays as parameters.

@jeeswg: About 'convenience':
If you look at my scripts you'll see that I rather often 'typed that manually'. Also, I usually type those 'optional' spaces and dots to separate parameters, operators, etc. It might not be 'convenient' when writing scripts, but it is 'convenient' for me when 'parsing' scripts whith my built-in parser, my eyes.

Re: if var in/contains comma-separated list/array

Post by jeeswg » 01 Feb 2018, 02:46

- I may say more at some point.

- Type these manually:

Code: [Select all]GeSHi © Codebox Plus

"abc,def,ghi,jkl,mno,pqr,stu,vwx,yz"

["abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "vwx", "yz"]

;bonus challenge:
{abc:"def", ghi:"jkl", mno:"pqr", stu:"vwx", y:"z"}

- Anyhow, I've written some prototype scripts for converting comma-separated lists to both types of arrays. Whether you use comma-separated lists in your script or not, I would never want to type out all of the double quotes manually. In fact, due to my hotstrings system, I almost never use the shift key at all.

Code: [Select all] [Expand]GeSHi © Codebox Plus

Re: if var in/contains comma-separated list/array

Post by coffee » 01 Feb 2018, 00:58

just me wrote:see also: StrSplit -> Delimiters

He posted
jeeswg wrote:This would be less inconvenient to type, but still a bit bulky:
if var contains StrSplit("Mon,Tue,Wed,Thu,Fri,Sat,Sun", ",")

So "StrSplit" is bulky apparently, a function that already exists, is implemented and "splits" a string into an object given the delimiter(s) of your desires. :roll:
As a user defined function? wrap it, nobody cares. Built-in? it's not really logical to have a different function for each possible delimiter character that a user may want to use.

jeeswg wrote:- Btw 'contains' to 'StrContains' is simple enough, but 'in' to 'StrIn' causes confusion with InStr. So perhaps 'StrExact' would be better, I'm not sure if there's a better candidate word.

StrContains has always seemed more intuitive than InStr *to me*, since the descriptive version of "InStr" using a supposed Str prefix is "StrInStr", and from an object approach contains makes more sense. Following justme's example, accepting a single string or an object containing multiple strings to check whether they are contained by the string subject.
StrInList seems a more descriptive approach to StrIn. But if InStr is ever replaced with StrContains, there shouldn't really be a problem with StrIn, though the upper case i looks like a lowercase L, to the ahk unaware user, it may come across as StrLn, which doesn't exist. Either way, the check is to see whether a whole string appears in a list of words, so there's no ambiguity as to the input. It will always be a word list to match against. As it is also supposed to be a more convenient version of multiple ORed (var="something").

For RegexMatch and RegexReplace, and StrReplace, a case could try to be made for StrMatch, as it is simple matching, like StrReplace is a simple replace, or perhaps StrCompare, with the assumption that for one match/comparison you use the "=" operator and multiple comparisons you use StrMatch or whatever the name is. But if the user doesnt read the documentation, there's no hand holding that the advantage is match against a word list, i.e no advantage in StrMatch(str, "value"). So "In" or "InList" may be more "you can't screw it up" obvious.

Code: [Select all]GeSHi © Codebox Plus

; Instead of
if (var="string1") || (var="string2") || (var=stringvar) || (var="string3")
do

; We use
if StrMatch/StrCompare(var, ["string1", "string2", stringvar, "string3"], case, ... remaining params)
do


"string1,string2,string3", convenient if short, guaranteed you are using string literals, all the time. Make it longer and it's just a wall of text/essay. Now add variables to it or any sort of dynamic referencing/expression and you have to start using concatenation.

Code: [Select all]GeSHi © Codebox Plus

"string1,string2," . CONSTANT . ",string3"
"string1,string2," . CONSTANT ",string3"
stringvar1 . "," . stringvar2 . ",string1,string2"


Code: [Select all]GeSHi © Codebox Plus

["string1", "string2", CONSTANT, "string3"]
[strinvar1, stringvar2, "string1", "string2"]

The first block is genuinely bad and it gets worse the more expressions you add, no clean division once it gets long, can't tab/space in between strings to increase legibility. Moreso, with the new continuation style of arrays, the whole thing can be even more list-like if overclarity is desired, easier editing/reading. Not sure why coding syntax should be simply ruled by a personal disability to use a keyboard, instead of following universal conventions compatible with almost anything and clearer.

jeeswg wrote:(Although for numbers, the [] syntax does remain useful.)
oArray := [1,2,3,4,5,6,7]

Above. It is always useful, e-v-e-n for s-t-r-i-n-g-s.



As for "contains" as expression (or whatever it is, operator? command?), does it return anything? is it simply bool like "is"? will it be like "~=" for regex? If there is string manipulation happening where you will need the position and you may want to "inline" inside another expression like substr, what's the feasibility of var contains "string" as an expression?

Re: if var in/contains comma-separated list/array

Post by nnnik » 31 Jan 2018, 07:36

Asinging to a variable is faster in any case actually - when you write [] in a expression it will once again create that array again.
It might be easy for you to comprehend CSL or anything once you encountered it since it fits your style - towards me my SyntaxTree class is also very easy once encountered.
What I'm saying is that one should always choose the standard way of handling things if you want others to use your code - which is why [] is prefereable for any code you share.
The fact that you have to use Backspace etc. in such an array shows me that you might be better off using a different editor.

Re: if var in/contains comma-separated list/array

Post by just me » 31 Jan 2018, 06:46

v1 docs wrote:The "contains" operator is the same as using IfInString/IfNotInString except that multiple search strings are supported (any one of which will cause a match).

Code: [Select all]GeSHi © Codebox Plus

InStr(Var, ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"])

see also: StrSplit -> Delimiters

Re: if var in/contains comma-separated list/array

Post by jeeswg » 31 Jan 2018, 04:45

- Btw 'contains' to 'StrContains' is simple enough, but 'in' to 'StrIn' causes confusion with InStr. So perhaps 'StrExact' would be better, I'm not sure if there's a better candidate word.

@nnnik:
- Would assigning to a variable be faster for a one-off use?
- I'm sympathetic re. [] being more instantly readable, but since there's no syntax for what I want, I chose a function name. Once encountered, CSL (or another name) is easy to comprehend.
- I recommend assigning variables and using comments, but not always: if ext in ["txt","xls"]
- I find "," quite taxing to type, and commonly have to use backspace to correct it, making it even slower. You could do human benchmark tests to see which you find easier to type. I could use a hotkey to convert a list into an array, but the function approach feels like the better approach.

Code: [Select all]GeSHi © Codebox Plus

csl("a,b,c")
["a","b","c"]

csl("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec")
["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]

csl("January,February,March,April,May,June,July,August,September,October,November,December")
["January","February","March","April","May","June","July","August","September","October","November","December"]

Re: if var in/contains comma-separated list/array

Post by Helgef » 31 Jan 2018, 04:24

nnnik wrote:And since I have bad memory
I just read the two posts in this thread and all I could remember was agreeing with you nnnik :lol:.

Re: if var in/contains comma-separated list/array

Post by nnnik » 31 Jan 2018, 03:35

PSL and CSL are bad. I don't understand why it is a pain to type an array - I don't have that issue
While CSL and PSL doesn't make any sense you could have just called it CSV which would at least mean something.
Generally speaking I would never bother reading code that contains such function names.
Readability is the most important thing when creating code and as studies have shown we humans are made for reading small words entirely.
So using CamelCase and words always is the only and the best option.
Flags or functionnames that are a combination of random letters are the perfect way for decreasing readability and the information a function name contains.
While everyone understood your first code perfectly I'm not so sure about everyone when it comes to the third or fourth example.
Also you should probably assign that array to a variable before comparing it. Not only would that make your code perfectly more readeable and solve any readability issues anyone might have - it also makes your code faster.

Code: [Select all]GeSHi © Codebox Plus

isWeekday( string ) {
static shortWeekDay := ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
if string contains shortWeekDay
}
Adding descriptive names allows you to skip over specific parts of reading someone elses code ´- a must have if you want someone else to read your code.
CSL and PSL are pretty much non-descriptive. Storing that in a value will probably make me look up what your function does before
I would probably have to read your function definition - something I wouldn't have to do when you would have just used [].
And since I have bad memory I probably wouldn't only read it once or twice. So while your Array is perfectly logical for everyone your CSL and PSL function pose a problem for everyone else.
So while your Array is bulky and CSL and PSL are not the Array is still the best thing we have.

if var in/contains comma-separated list/array

Post by jeeswg » 31 Jan 2018, 00:59

At the moment in AHK v1, we have:
if var contains Mon,Tue,Wed,Thu,Fri,Sat,Sun

In AHK v2, this would probably become:
if var contains ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]
Which is far less convenient.
Such lists are inconvenient to type, although hotkeys to prepare the text are possible.

This would be made more bulky by script correctors that automatically separate parameters.
if var contains ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
(You might say 'don't use a corrector', but in general I've found that it's better to use one than not to use one, and that it's simpler to apply it to all arrays than to try to make exceptions.)

This would be less inconvenient to type, but still a bit bulky:
if var contains StrSplit("Mon,Tue,Wed,Thu,Fri,Sat,Sun", ",")

A workaround:
if var contains CSL("Mon,Tue,Wed,Thu,Fri,Sat,Sun")
if var contains PSL("Mon|Tue|Wed|Thu|Fri|Sat|Sun")
CSL/PSL aren't too bad, but using that every time?

An alternative. Something like this perhaps!?
if var containsCSL "Mon,Tue,Wed,Thu,Fri,Sat,Sun"

Some further alternatives.
if StrContains(var, "Mon,Tue,Wed,Thu,Fri,Sat,Sun", "D,")
if StrContains(var, "Mon|Tue|Wed|Thu|Fri|Sat|Sun", "D|")
if StrContainsCSL(var, "Mon,Tue,Wed,Thu,Fri,Sat,Sun")

Also, there's RegExMatch. But this has the drawbacks of: checking for characters that need escaping, having to use pipes, being slow.
if RegExMatch(var, "Mon|Tue|Wed|Thu|Fri|Sat|Sun")

Btw I would generally never use [] to define an array, I would always use something like CSL if available:
oArray := ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]
oArray := CSL("Mon,Tue,Wed,Thu,Fri,Sat,Sun")
(Although for numbers, the [] syntax does remain useful.)
oArray := [1,2,3,4,5,6,7]

I believe that most people including myself: (a) see delimiter-separated strings as a bit old-fashioned cf. arrays, (b) see it as hard to justify interpreting a string as comma-delimited by default. However, the comma/pipe-separated list remains very useful.

I believe also that in AHK v1, and in AHK v2 alpha at the moment, arrays are almost never used as input parameters for functions, and so key issues, and the practical reality of their day-to-day use, haven't really been considered yet. Because it's new territory, and because it takes some time to work out how to develop a new syntax, I am concerned that it's the sort of thing where people might not quite get the syntax right and potentially end up saying: we need to fix this in AHK v3.

Thanks for reading.

Top