Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: Hash/Array slice : how to exclude items?

by LanX (Saint)
on Jan 24, 2023 at 14:15 UTC ( [id://11149821]=note: print w/replies, xml ) Need Help??


in reply to Hash/Array slice : how to exclude items?

I suppose that you know that %hash{...} is a new slice syntax that returns the keys too, and that's your intention.

Regarding your syntax

> %hash{-'schema', -'log'}

Well "-" has a meaning in arrays, so I'd rather prefer something else like "!"

But this would get messy if the list also included non-negated elements,

%hash{'schema', -'log'} # WHAT???

so for the sake of a clean design one would rather do only one negation

%hash{! 'schema', 'log'}

I'm not aware of a built-in syntax to do this, but it's basically syntactic sugar for a grep, see demo in debugger

DB<1> @hash{'schema','log',a..c}=('s','l',1..3) DB<2> x \%hash 0 HASH(0x3168da0) 'a' => 1 'b' => 2 'c' => 3 'log' => 'l' 'schema' => 's' DB<3> x +{ %hash{grep !/^schema|log$/, keys %hash } } # Note ° 0 HASH(0x32e09d8) 'a' => 1 'b' => 2 'c' => 3 DB<4>

I know you didn't want grep, but this offers many flexibilities, like dynamically deciding what to exclude.

Cheers Rolf
(addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
Wikisyntax for the Monastery

°) the +{...} is just an anonymous hash for pairwise dump

Replies are listed 'Best First'.
Re^2: Hash/Array slice : how to exclude items?
by LanX (Saint) on Jan 24, 2023 at 14:34 UTC
    you can also design your own pseudo-operator ->$exclude

    DB<7> $exclude = sub { my $href = shift; my $excl= join '|', @_; r +eturn +{ %$href{ grep !/^$excl$/, keys %$href } } } DB<8> x $h_ref 0 HASH(0x3168da0) 'a' => 1 'b' => 2 'c' => 3 'log' => 'l' 'schema' => 's' DB<9> x $h_ref->$exclude(qw/log schema/) 0 HASH(0x32e1158) 'a' => 1 'b' => 2 'c' => 3 DB<10>

    Cheers Rolf
    (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
    Wikisyntax for the Monastery

      x +{ %hash{grep !/^schema|log$/, keys %hash } }

      $exclude = sub  { my $href = shift;  my $excl= join '|', @_; return  +{ %$href{ grep !/^$excl$/, keys %$href } } }

      Noting, of course, that because there are no parentheses in either of these regex, the ^ anchor only applies to the first term in the alternation list, the $ anchor only applies to the final term in the alternation list, and any intermediate terms will be completely unanchored, which means that it's likely to exclude more keys than you might think: therefore, running ->exclude(qw/log schema/) will not necessarily match running ->exclude(qw/schema log/) , depending on the keys of the hash, which may or may not have been the intention.

      DB<1> @hash{'schema','log',a..c, 'schematic', 'blog'}=('s','l',1..3, +'circuit','rant') DB<2> x \%hash 0 HASH(0x3da37a8) 'a' => 1 'b' => 2 'blog' => 'rant' 'c' => 3 'log' => 'l' 'schema' => 's' 'schematic' => 'circuit' DB<3> x +{ %hash{grep !/^schema|log$/, keys %hash } } # Note that t +he ^ only applies to schema, and the $ only applies to log, so it wil +l remove more than you might have meant 0 HASH(0x3f6e6f8) 'a' => 1 'b' => 2 'c' => 3 DB<4> x +{ %hash{grep !/^(schema|log)$/, keys %hash } } # This vers +ion has all exclusions fully anchored 0 HASH(0x3f6ed10) 'a' => 1 'b' => 2 'blog' => 'rant' 'c' => 3 'schematic' => 'circuit' DB<5> $exclude1 = sub { my $href = shift; my $excl= join '|', @_; +return +{ %$href{ grep !/^$excl$/, keys %$href } } } DB<6> $h_ref = \%hash DB<7> x $h_ref->$exclude1(qw/schema log/) 0 HASH(0x3f73640) 'a' => 1 'b' => 2 'c' => 3 DB<8> x $h_ref->$exclude1(qw/log schema/) 0 HASH(0x3f73988) 'a' => 1 'b' => 2 'blog' => 'rant' 'c' => 3 'schematic' => 'circuit' DB<9> $exclude2 = sub { my $href = shift; my $excl = join '|', @_; r +eturn +{ %$href{ grep !/^($excl)$/, keys %$href } } } DB<10> x $h_ref->$exclude2(qw/schema log/) 0 HASH(0x3f73808) 'a' => 1 'b' => 2 'blog' => 'rant' 'c' => 3 'schematic' => 'circuit'
        Well spotted by you and badly tested by me, thanks.

        In the end the regex is a poor man's alternative for the unfortunately designed smartmatch operator ~~

        Actually I was too occupied worrying if I need to quotemeta the input or if keeping the door open for regex-metas is a better interface, and forgot about precedence here.

        So another "fault" in the concept. =)

        Cheers Rolf
        (addicted to the 𐍀𐌴𐍂𐌻 Programming Language :)
        Wikisyntax for the Monastery

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11149821]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (8)
As of 2024-04-24 09:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found