Quoting from Perldoc for apply in List::AllUtils
Applies BLOCK to each item in LIST and returns a list of the values after BLOCK has been applied. In scalar context, the last element is returned. This function is similar to "map" but will not modify the elements of the input list.
I want to check whether the number is an Armstrong number or not. Since map in scalar context returns the number of elements and apply returns the last element which is final $sum. I used the following
#!/usr/bin/perl
use List::AllUtils qw(apply sum);
use v5.10;
use strict;
use warnings;
say "Enter the input : ";
my $input_number = <STDIN>;
chomp($input_number);
my $sum;
my $out = apply { $sum += $_ ** 3 } split //, $input_number ;
say $out;
I expect $sum to be returned to $out. But I get the last character of $input_number.
Output :
Enter the input :
153
3
Edit :
I have the solution for Armstrong number. I need to know why the apply doesn't return $sum and returned the last character of $input_number.
You don't need apply or map, just a for loop:
my $input_number = 153;
my $sum = 0;
$sum += $_ ** 3 for split //, $input_number ;
print ($sum == $input_number) ? "Yep, it's an armstrong num\n" : "nope\n";
If you wanted to pull the last element, you could do that like the following:
my $out = (map {$sum += $_ ** 3} split //, $input_number)[-1];
To show what apply is actually does, one can just look at the source:
sub apply (&@) {
my $action = shift;
&$action foreach my @values = @_;
wantarray ? @values : $values[-1];
}
This makes a copy of the original array, and then runs the code block on each element. Note though, that you must actually change the value of $_ or apply will simply return the original element.
I believe apply was intended specifically for the case of applying a regular expression to an array without being destructive to the original array. For example, the following are equivalent:
my @newarray = apply {s/\n//g} @oldarray;
my @newarray = map {my $text = $_; $text =~ s/\n//g; $text} @oldarray;
So ultimately, the only way to get apply to work in the way you expect with your code is to do the following:
my $out = apply { $_ = $sum += $_ ** 3 } split //, $input_number ;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With