Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

get it into one line ?

by physi (Friar)
on Apr 16, 2001 at 12:58 UTC ( [id://72789]=perlquestion: print w/replies, xml ) Need Help??

physi has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm trying to 'convert' the following code into an oneliner
But I can't.
my %sec; my $newsecret; for my $char (split //, $secret){ next if exists $sec{$char}; $newsecret .= $char; $sec{$char}++; }
Ok this code should delete all multiple chars in $secret. The result is in $newsecret afterwards.

Now I tried it with a map-Statement:

$newsecret = join '', map { ??? } split //, $secret;
But what has to be written into the { } part ?
I'd tried this one:
my $newsecret = join '', map { my $char=$_; $_='' if exists $sec{$_}; +$sec{$char}++} split //, $secret;
But that results in numberfilled array $newsearch string.

Any ideas ? Thanks

----------------------------------- --the good, the bad and the physi-- -----------------------------------

Replies are listed 'Best First'.
Re: get it into one line ?
by athomason (Curate) on Apr 16, 2001 at 13:49 UTC
    > Ok this code should delete all multiple chars in $secret.

    This spec is a bit uncertain: do you want to eliminated sequentially repeated characters ('bookkeeper' -> 'bokeper') or keep only one instance of each character ('bookkeeper' -> 'bokepr')? Gathering from your first attempt, you want the second behavior.

    As an exercise, I'll demonstrate both, since they're both easy with regular expressions. Though your hash approach makes sense and is likely more efficient, I like the elegance of regexen. As always, TMTOWTDI.

    The first case is quite simple; just use:($newsecret = $secret) =~ tr/a-zA-Z//s;The /s flag instructs the transliteration operator to squash any repeated characters that are replaced. The empty replacement list causes the search list to be copied into the replacement list. So, the operator matches any character, replaces it with itself, and eliminates any sequential duplicates it comes along.

    The second form takes a little bit more ninja magic, but I hope it's still understandable. After all, you're looking for concise, not pretty: for ( $newsecret = $secret; $newsecret =~ s/(([a-zA-Z]).*)\2/$1/; ){1};

    You can't just use /g because the replacements should happen right to left. This is an ugly form of the 1 while (...) construct that sneaks the initial assignment into the line. If you don't mind modifying $secret in-place, you should use the cleaner form:1 while $secret =~ s/(([a-zA-Z]).*)\2/$1/;

    The regexp finds any character followed by the same character later in the string and crops the latter. This is repeated until it no longer matches.

    An important point is that I've assumed $secret contains only alphabetic characters. You'll need to change the matching character class according to the actual contents of your variable.

    Though I doubt it applies to your case, if the final order of the string doesn't matter then you could use the hash method:

    $newsecret = join '', keys %{{map {($_, 1)} split //, $secret}};

Re: get it into one line ?
by repson (Chaplain) on Apr 16, 2001 at 14:40 UTC
    You could do it like this:
    $newsecret = do { my %hash; join('', map { $hash{$_}++ ? () : $_ } (split //, $secret)); }; The do creates a new scope so that the hash isn't in scope outside the area it is needed.
    However I would probably use a regex like athomason's above.
Re: get it into one line ?
by Eureka_sg (Monk) on Apr 16, 2001 at 14:54 UTC

    Just a gentle pointer

    But that results in numberfilled array $newsearch string

    The map function evaluates whatever is inside {} and returns the result from the last expression in the block. Thus, it's giving you a list of numbers generated from $sec{$char}++.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-04-26 00:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found