# Translate the var $nums into an integer list
use strict;
my @allnums;
my $nums ='30-32,34,50,54-56';
my @nums = split /,/, $nums;
for my $numstr (@nums) {
if ($numstr =~ /-/) {
my ($lower, $upper) = split /-/, $numstr ;
for my $anum ($lower .. $upper) {
push @allnums, $anum;
}
} else {
push @allnums, $numstr;
}
}
use Data::Dumper;die 'DDDEBUG' . Dumper(\@allnums);
#Numbers 34 and 50 below have quote around them but i dont want it.
DDDEBUG$VAR1 = [
30,
31,
32,
'34',
'50',
54,
55,
56
];
You have an X-Y problem. This is where you are asking for X, because you
think it is what you need for Y, but you are mistaken. What are you
actually trying to do? There are very few circumstances in Perl where
you need to care about a scalar's internal storage format (and all of
those are considered unfixable bugs rather than features).
Ben
> Following code has quoted numbers in it, but i want
> just integers. What's easiest way?
> } else {
> push @allnums, $numstr;
push @allnums,$numstr * 1
> }
> }
Note that instead of
> my $nums ='30-32,34,50,54-56';
and processing this, you could do:
my @allnums = (30..32,34,50,54..56);
if you're just looking for an easier notation.
--
John Bokma
Read my blog: http://johnbokma.com/
Hire me (Perl/Python): http://castleamber.com/
Better use
push @allnums, $lower .. $upper;
Ilya
You could also use Set::IntSpan, which does that sort of thing.
#!/usr/bin/perl
use strict;
use warnings;
use Set::IntSpan;
use Data::Dumper;
my $nums ='30-32,34,50,54-56';
my $set = Set::IntSpan->new( $nums );
my @nums = $set->elements();
print Dumper \@nums;
$VAR1 = [
30,
31,
32,
34,
50,
54,
55,
56
];
The $num variable represents user input. If they enter 5-20 i
need to push all the integers in between on an array and then
process whatever else is entered in CSV form. I got around the problem
by doing
for (@allnums) {
push @allnums, ($numstr * 1); # Turns string to int easy way
}
Still not sure why original code had a quoted value e.g. '11'
instead of the number.
mp> Ben Morrow wrote:
>> Quoth monkeys paw <us...@example.net>:
>>> Following code has quoted numbers in it, but i want
>>> just integers. What's easiest way?
>>
>> You have an X-Y problem. This is where you are asking for X, because you
>> think it is what you need for Y, but you are mistaken. What are you
>> actually trying to do? There are very few circumstances in Perl where
>> you need to care about a scalar's internal storage format (and all of
>> those are considered unfixable bugs rather than features).
>>
>> Ben
>>
mp> The $num variable represents user input. If they enter 5-20 i
mp> need to push all the integers in between on an array and then
mp> process whatever else is entered in CSV form. I got around the problem
mp> by doing
mp> for (@allnums) {
mp> push @allnums, ($numstr * 1); # Turns string to int easy way
mp> }
huh?? perl doesn't need to convert strings to nums in general.
mp> Still not sure why original code had a quoted value e.g. '11'
mp> instead of the number.
did you read any of the followups? in particular the one about the
module that does this for you? lists of number ranges is an old format
and the problem has long been solved. use the module.
uri
--
Uri Guttman ------ u...@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
Users enter it this way, if i changed the string
as you suggest i guess i could use an eval:
$nums ='30-32,34,50,54-56';
$nums =~ s/\-/\s\.\.\s/; # Spaces important
now $nums = 30 .. 32,34,50,54 .. 156
How could i eval $nums into an array so it
would equal 30,31,32,34, etc...
eval { @allnums = $nums }; # This definitely won't work
mp> Users enter it this way, if i changed the string
mp> as you suggest i guess i could use an eval:
mp> $nums ='30-32,34,50,54-56';
mp> $nums =~ s/\-/\s\.\.\s/; # Spaces important
mp> now $nums = 30 .. 32,34,50,54 .. 156
mp> How could i eval $nums into an array so it
mp> would equal 30,31,32,34, etc...
mp> eval { @allnums = $nums }; # This definitely won't work
USE THE MODULE!!!
lather. rinse. repeat.
you are not good enough to code this correctly. even with working code
given to you.
my ($low, $high) = split /-/, $num;
push @array, $low..$high;
jue
>Following code has quoted numbers in it, but i want
>just integers. What's easiest way?
>
[snip]
> push @allnums, $numstr;
^^
1*$numstr;
This works because of context, didn't read other responces
which I will later.
-sln
Eval would work. If you don't care about validation,
I guess you could do it a couple of ways:
use strict;
use warnings;
my $input = '30-32,34,50,54-56';
$input =~ s/-/../g;
#my @allnums;
#push @allnums, eval $input;
# or
my @allnums = (eval $input);
use Data::Dumper;die 'DDDEBUG' . Dumper(\@allnums);
__END__
DDDEBUG$VAR1 = [
30,
31,
32,
34,
50,
54,
55,
56
];
-sln
>On Wed, 16 Dec 2009 00:54:09 -0500, monkeys paw <us...@example.net> wrote:
>
>my @allnums = (eval $input);
^^
Note that eval's can execute code, so user input can cause harm:
my $input = 'print "shit happens\n";30-32,34,50,54-56';
my @allnums = (eval $input);
*> shit happens
-sln
The easy answer is to say: Don't use Data::Dumper. There's no way
to tell if a number is a string (or rather, it's difficult) if you
don't use Data::Dumper;
Rewrite your die() line like this:
die "DDDEBUG: @allnums\n";
Seriously, apart from using Data::Dumper, there is pretty much no
simple or straightforward way to tell if a number is a string. Your
code won't even know. So you won't have to worry about if your code
will fail with a "stringed" number, as all strings that can be numbers
are converted seamlessly when used as a number.
But if you still want Data::Dumper to refuse to see the number as a
string, you can use this line:
$_ += 0 foreach @allnums; # "numerate" each element
Remember, unless you print out Data::Dumper's output, your program
won't behave any differently with that line or without. And since you
seem to be using Data::Dumper just for inspection purposes, there
doesn't seem to be any reason to "numerate" your strings.
So I have to ask: Why is it so important that Data::Dumper not
return the numbers as strings, when the rest of Perl can't even tell?
-- Jean-Luc
Thats funny and a good point.
i found several ways that work, and as uri
points out, perl interprets numbers and strings for you,
even if an array element has quotes, as long
as it is numerical it will be interpreted correctly.
@a = (
35,
'35',
);
Either element is a valid int.
mp> i found several ways that work, and as uri
mp> points out, perl interprets numbers and strings for you,
mp> even if an array element has quotes, as long
mp> as it is numerical it will be interpreted correctly.
array elements don't have quotes. dumper showed quotes as you had left
those values as strings. please learn to explain things correctly.
mp> @a = (
mp> 35,
mp> '35',
mp> );
mp> Either element is a valid int.
only after you use them as numbers.
and one more time, use a module for this. you still haven't said
anything about the module that does this for you. why not?
My hand rolled code worked well enough, i didn't bother installing
Int::Span, though it certainly is aimed at the heart of the problem.
Also, other than just interpreting the numbers, i had to fill an array
with extra data based on the number, so Int::Span would only be a
smaller percentage of the overall data problem. Thanks.
>
> uri
>