Home > Back-end >  how to count occurrences of a character in a string without assigning the count explicitly to a vari
how to count occurrences of a character in a string without assigning the count explicitly to a vari

Time:11-22

I want to report the number of times a character occurs in a string. Thanks to Is there a better way to count occurrence of char in a string?, the first part of the following works elegantly.

#!/usr/bin/env perl
use strict; use warnings;
my $string='dog
#
####
pig horse';
# https://stackoverflow.com/questions/34437248/is-there-a-better-way-to-count-occurrence-of-char-in-a-string
print join('','# occurs ',my$dummy=()=$string=~/[#]/g,' times in',"\n",$string,"\n",);

# the following yields no count at all:
print join('','# occurs ',()=$string=~/[#]/g,' times in',"\n",$string,"\n",);

Is there a way to eliminate the seemingly gratuitous declaration of the $dummy variable? I'd like to use that integer directly in join without first declaring a variable to grab the value.

CodePudding user response:

That trick

$dummy = () = $string =~ /[#]/g

works because the whole assignment-expression

() = EXPR

itself is in a scalar context, being assigned to a scalar ($dummy), so it returns the length of the would-be list which EXPR returns (it being in list context).

So impose the scalar context on it

say join('', '# occurs ', scalar( () = $string =~ /#/g ),' times');

I've shortened the string for easier reading, and employed say instead of print ... "\n".

See this page for more on () = EXPR and its context, and the links in it.

Not sure that this is really much prettier but it does what is asked.

But if you really always want just one character's count than tr does it much more nicely

print join('', '# occurs ', $string =~ tr/#//,' times in',"\n",$string,"\n",);

If one were to really just print then there is no need to form a string with join '' since print takes a list and effectively concatenates elements without anything in between, so joins them

say '# occurs ', scalar( () = $string =~ /#/g ), " times in\n", $string;

or, for a single character

say '# occurs ', $string =~ tr/#//, ' times in', "\n", $string;

(But I take it that the print is just an example for this question and that you really need a string...)

  • Related