Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^2: Removing a string-element from an array of strings

by Anonymous Monk
on Jul 26, 2020 at 16:31 UTC ( #11119831=note: print w/replies, xml ) Need Help??


in reply to Re: Removing a string-element from an array of strings
in thread Removing a string-element from an array of strings

Here is what I am after:

@history = ( "Cache::SizeAwareMemoryCache(3)" , "dhcp-options(5)" , "B +N_add_word(3)" , "audit-packages(8)" ) $choice = "dhcp-options(5)"
Find the value of choice in the array "@history", remove it, and cat it to the end of the array.

I found an example that works on an array with the form @array = ( "aaaa" , "bbbb" , "cccc" , "dddd" ), but it refuses to work for my @history array ( the parens in the string(s) ? ) Notice all the elements are in char-string format -- thats that I indended to say. Since the first element contains "::", will that be of any consequence?

Sorry for the confusion

Replies are listed 'Best First'.
Re^3: Removing a string-element from an array of strings
by AnomalousMonk (Bishop) on Jul 26, 2020 at 17:58 UTC
    I found an example that works on an array with the form @array = ( "aaaa" , "bbbb" , "cccc" , "dddd" ), but it refuses to work for my @history array ( the parens in the string(s) ? )

    Impossible to say. You've provided no code to examine.

    Here's something that may work IIUC your requirements:

    c:\@Work\Perl\monks>perl -wMstrict -le "use List::MoreUtils qw(part); ;; my @history = qw(Cache::SizeAwareMemoryCache(3) dhcp-options(5) BN_ad +d_word(3) audit-packages(8)); my $choice = 'dhcp-options(5)'; print qq{before: (@history)}; ;; @history = map @$_, part { $_ ne $choice ? 0 : 1 } @history; print qq{after: (@history)}; " before: (Cache::SizeAwareMemoryCache(3) dhcp-options(5) BN_add_word(3) + audit-packages(8)) after: (Cache::SizeAwareMemoryCache(3) BN_add_word(3) audit-packages( +8) dhcp-options(5))
    Note that this will remove and append all matching strings to the end of the array, not just the first one. See List::MoreUtils::part().

    WRT this comment by LanX which I just saw, note that the solution above uses exact string comparison, not regex comparison. If you're using regexes, the approach must be slightly different.


    Give a man a fish:  <%-{-{-{-<

Re^3: Removing a string-element from an array of strings
by choroba (Archbishop) on Jul 27, 2020 at 14:28 UTC
    You can also use the stable sort, sorting by whether the string equals the choice. The ones that don't will be sorted as zeroes, i.e. at the beginning of the list, the one that does will be sorted as 1, i.e. will go to the end of the list.
    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use sort 'stable'; use List::UtilsBy qw{ sort_by }; my @history = ( 'Cache::SizeAwareMemoryCache(3)' , 'dhcp-options(5)' , + 'BN_add_word(3)' , 'audit-packages(8)' ); my $choice = 'dhcp-options(5)'; @history = sort_by { $_ eq $choice } @history; say "@history";

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re^3: Removing a string-element from an array of strings
by LanX (Cardinal) on Jul 26, 2020 at 17:30 UTC
    This seems to be a continuation of the thread about parsing man pages. (HELP! I am in regex-hell)

    Your post is hard to read because of missing <code> tags!

    (If you had logged in you'd be capable to edit and fix it.)

    Anyway my guess is that you need quotemeta resp. \Q because parens () are metacharacters in regexes, which need to be escaped.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re^3: Removing a string-element from an array of strings
by Cristoforo (Curate) on Jul 26, 2020 at 18:55 UTC
    As LanX said, you need to use quotemeta(or \Q) for the parentheses.

    Here might be what you want.

    #!/usr/bin/perl use strict; use warnings; my @history = ( "Cache::SizeAwareMemoryCache(3)" , "dhcp-options(5)" , + "BN_add_word(3)" , "audit-packages(8)" ); my $choice = "dhcp-options(5)"; @history = grep !/\Q$choice\E/, @history; # '\Q' to quotemeta push @history, $choice; print "@history";
    Prints:

    C:\Old_Data\perlp>perl test3.pl Cache::SizeAwareMemoryCache(3) BN_add_word(3) audit-packages(8) dhcp-o +ptions(5) C:\Old_Data\perlp>
      push @history, $choice;

      What if the $choice was not found in the @history array?


      Give a man a fish:  <%-{-{-{-<

Re^3: Removing a string-element from an array of strings
by AnomalousMonk (Bishop) on Jul 26, 2020 at 21:30 UTC

    Here's another approach if you're looking for an exact string match for one of multiple choices:

    c:\@Work\Perl\monks>perl -wMstrict -le "use List::MoreUtils qw(part); ;; my @history = qw(Foo::End(3) dhcp-options(5) Back_word(3) audit-packa +ges(8)); print qq{before: (@history)}; ;; my %choices = map { $_ => 1 } qw(Back_word(3) Foo::End(3)); ;; @history = map @$_, part { exists $choices{$_} } @history; print qq{after: (@history)}; " before: (Foo::End(3) dhcp-options(5) Back_word(3) audit-packages(8)) after: (dhcp-options(5) audit-packages(8) Foo::End(3) Back_word(3))


    Give a man a fish:  <%-{-{-{-<

Re^3: Removing a string-element from an array of strings
by kcott (Bishop) on Jul 28, 2020 at 04:37 UTC

    Treating your code as some sort of sentient entity which "refuses to work" will get you nowhere. Your code is no doubt doing exactly what you asked it to do; the problem will be what you asked.

    If you do not show your code, along with its output which may consist solely of some error message, we cannot help you! Please read "How do I post a question effectively?" and SSCCE; then provide us with something that we can use to help you.

    Your requirements have changed. You now additionally want "... and cat it to the end of the array."; however, you don't say what happens if the element to be removed doesn't exist.

    There are a lot posts involving regexes. Based on what you've told us so far, I see no need for the overhead of firing up the regex engine.

    I originally provided:

    $ perl -E 'my @x = qw{A B C D}; @x = grep $_ ne "B", @x; say "@x"' A C D

    With your new additional requirement, you could code:

    $ perl -E 'my @x = qw{A B C D}; my $y = "B"; @x = (grep($_ ne $y, @x), + $y); say "@x"' A C D B

    If "B" is not found, you perhaps want

    $ perl -E 'my @x = qw{A B C D}; my $y = "Z"; @x = (grep($_ ne $y, @x), + $y); say "@x"' A B C D Z

    or

    $ perl -E 'my @x = qw{A B C D}; my $y = "Z"; @x = (grep($_ ne $y, @x), + $y)[0..$#x]; say "@x"' A B C D

    Which still works if "B" is found:

    $ perl -E 'my @x = qw{A B C D}; my $y = "B"; @x = (grep($_ ne $y, @x), + $y)[0..$#x]; say "@x"' A C D B

    Because these methods simply use string inequality (ne) you won't encounter problems with characters being special to a regular expression:

    $ perl -E 'my @history = qw{Cache::SizeAwareMemoryCache(3) dhcp-option +s(5) BN_add_word(3) audit-packages(8)}; my $choice = "dhcp-options(5) +"; @history = (grep($_ ne $choice, @history), $choice); say "@history +"' Cache::SizeAwareMemoryCache(3) BN_add_word(3) audit-packages(8) dhcp-o +ptions(5) $ perl -E 'my @history = qw{Cache::SizeAwareMemoryCache(3) dhcp-option +s(5) BN_add_word(3) audit-packages(8)}; my $choice = "not-found(0)"; +@history = (grep($_ ne $choice, @history), $choice); say "@history"' Cache::SizeAwareMemoryCache(3) dhcp-options(5) BN_add_word(3) audit-pa +ckages(8) not-found(0) $ perl -E 'my @history = qw{Cache::SizeAwareMemoryCache(3) dhcp-option +s(5) BN_add_word(3) audit-packages(8)}; my $choice = "dhcp-options(5) +"; @history = (grep($_ ne $choice, @history), $choice)[0..$#history]; + say "@history"' Cache::SizeAwareMemoryCache(3) BN_add_word(3) audit-packages(8) dhcp-o +ptions(5) $ perl -E 'my @history = qw{Cache::SizeAwareMemoryCache(3) dhcp-option +s(5) BN_add_word(3) audit-packages(8)}; my $choice = "not-found(0)"; +@history = (grep($_ ne $choice, @history), $choice)[0..$#history]; sa +y "@history"' Cache::SizeAwareMemoryCache(3) dhcp-options(5) BN_add_word(3) audit-pa +ckages(8)

    — Ken

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2020-11-27 07:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?