Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check if something is an elem of a qw?

Tags:

raku

According to the documentation <a b c d e> and qw|a b c d e| are similar, and furthermore they both make lists, which means they should be equivalent to ('a', 'b', 'c', 'd', 'e').

Why then am I not able to do this: '2' (elem) <1 2 3 4 5>?

2 (elem) <1 2 3 4 5> doesn't work either, but 'a' (elem) <a b c d e> DOES.

What's going on? Shouldn't I be able to check the existence of the number like anything else?

like image 511
Electric Coffee Avatar asked Jun 01 '20 13:06

Electric Coffee


People also ask

How do you know if a set has an element?

The standard solution to check for existence of an element in the set container ( std::set or std::unordered_set ) is to use its member function find() . If the specified element is found, an iterator to the element is returned; otherwise, an iterator to the end of the container is returned.

How do you check if an element belongs to a list?

We can use the in-built python List method, count(), to check if the passed element exists in the List. If the passed element exists in the List, the count() method will show the number of times it occurs in the entire list. If it is a non-zero positive number, it means an element exists in the List.

How do you check if an element is in a list R?

To check if specific item is present in a given list in R language, use %in% operator. %in% operator returns TRUE if the item is present in the given list, or FALSE if not.

How do you check if element does not exist?

To check if an element does not exist in the DOM: Use the getElementById or querySelector methods to select the element. Check if the stored value is equal to null . If the value is equal to null , the element does not exist in the DOM.

How to check if an element exists in the list?

If it is a non-zero positive number, it means an element exists in the List. Code #3 : Demonstrating to check the existence of elements in the list using count (). Writing code in comment?

How to check if an element is hidden with display none?

if (window.getComputedStyle(x).display === "none") { // Do something.. Try it Yourself » Note:When an element is hidden with display:none(like in the example above), the element will not take up any space. To find out if an element is hidden with visibility:hidden, see the example below. This "hidden" element will take up space.

How to check if an element is in two lists at once?

Python - checking if an element is in two lists at the same time - Stack Overflow In Python, to check if an element is in two lists, we do if elem in list1 and elem in list2: if elem in (list1 and list2):

How to check if an element is present in an array?

If the element found, the flag value will change inside the if condition and that’s how we can check whether it is present or not. Now let’s consider another method of checking if the element is present in the array or not. It's the includes () method, which is now commonly used.


Video Answer


3 Answers

If you do :

<1 2 3 4 5>.raku.say

You'll see that it creates a list of IntStr objects (which are objects that can be either a String or an Integer). When we put these in a set we get a Set of IntStr objects.

The problem is (elem) doesn't use smart-matching but equivalence and neither the Int 1 or the String "1" are equivalent to IntStr.new(1, "1"). They do both smart-match with the IntStr...

You probably want to use first to find the needle :

defined <1 2 3 4 5>.first( 2, :k )

first( $match, :k ) returns the index of the first matching item and Nil if there's no match. So we test to see if it's defined and if so our item exists.

Or you can cast your list to String ot Integers using a map.

2 (elem) <1 2 3 4 5>.map( *.Int )
like image 133
Scimon Proctor Avatar answered Oct 25 '22 17:10

Scimon Proctor


So first off <…> is actually the same as:

q:w:v < … >

Or more verbosely:

Q :single :words :val < … >

The q or :single is how you specify the semantics of single quotes.

'abc'
q 'abc'
Q :q 'abc'
Q :single 'abc'

The :w or :words specifies that you want the string to be split on whitespace.

Q :w     ' a b   c '    eqv    'a', 'b', 'c'
Q :words ' a b   c '    eqv    'a', 'b', 'c'

The :v or :val specifies that you want val() semantics.
Using val will turn a string representing a number into something that is both a string and a number.

Q :v   '123'
Q :val '123'
val( '123' )
IntStr.new( 123, '123' )

Note that you can combine Q, q, or qq with a single character option

qw 'a b'   =:=   q:w 'a b'  =:=  q:words 'a b'
qb 'a\n'   =:=   q:b 'a\n'  =:=  q:backslash 'a\n'
qs 'a$_'   =:=   q:s 'a$_'  =:=  q:scalar 'a$_'

(It is probably a bug that qv'' doesn't work.)


At any rate (elem) and all Set/Bag/Mix operators deal with specific things, not generalities.

1.0    (elem)   1,2,3; # False
1      (elem)   1,2,3; # True

So if anything is different, those operators treat them as different things.

q:v '1'   (elem)   1; # False
q:v '1'   (elem)   IntStr.new(1,'1'); # True

<1>   (elem)   1; # False
<1>   (elem)   IntStr.new(1,'1'); # True

As we've established <1> wouldn't return an Int, it returns an IntStr.
An IntStr isn't exactly the same as an Int so it doesn't match an Int.


Presumably you want numeric things to only be numeric.

​< a b c 1 2 3 >.duckmap:  -> Numeric $_ { +$_ }

This goes through the list and anything that is already Numeric will get this function called on it.
The function does only one thing, call prefix:« + » which calls .Numeric on the value.

Since an IntStr is an Int which does Numeric, the function will be called on those values.


You may be wondering why <…> uses val semantics.

The reason is there is no way to know if you plan on giving it to a function that needs a Str or something Numeric.

sub foo ( Str ){}
sub bar ( Int ){}

foo <1>;
bar <1>;

foo 1;   # Failure
bar '1'; # Failure
like image 32
Brad Gilbert Avatar answered Oct 25 '22 18:10

Brad Gilbert


check if something is an element

The only coercion that (elem) applies is the minimum necessary to enable its right hand side argument to accept a set operation. It does not coerce at the element level and instead does strict comparison of values. So you must apply your own explicit coercion, for example:

'2' (elem) qw<1 2 3>                   ; # True
'2' (elem) ~«<1 2 3>                   ; # True
'2' (elem)   <1 2 3>».Str              ; # True
'2' (elem)   <1 2 3> .map: *.Str       ; # True

2   (elem) +«<1 2 3>                   ; # True
2   (elem)   <1 2 3>».Int              ; # True
2   (elem)   <1 2 3> .map: *.Int       ; # True

'2' (elem)   <a 2> .duckmap: *.Int     ; # False
2   (elem)   <a 2> .duckmap: *.Int     ; # True
'a' (elem)   <a 2> .duckmap: *.Int     ; # False

'2' (elem)   <a 2> .duckmap: *.Str     ; # True
2   (elem)   <a 2> .duckmap: *.Str     ; # False
'a' (elem)   <a 2> .duckmap: *.Str     ; # True

«/» distribute an operation to the leaves of their tree or list argument(s). For example, distributes a prefix +, which coerces its argument to a number.

duckmap is somewhat similar to «/»; one major difference is that it just continues if an operation doesn't apply. That is to say, a trial bind (function call) is attempted for each element; if the type signature matches, the function is called and its return value(s) replace that element, otherwise the element is just retained in the result as is.

like image 34
raiph Avatar answered Oct 25 '22 16:10

raiph