Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

push integers from strings

0 views
Skip to first unread message

monkeys paw

unread,
Dec 15, 2009, 8:27:37 PM12/15/09
to
Following code has quoted numbers in it, but i want
just integers. What's easiest way?

# 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
];

Ben Morrow

unread,
Dec 15, 2009, 8:40:13 PM12/15/09
to

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

John Bokma

unread,
Dec 15, 2009, 9:48:13 PM12/15/09
to
monkeys paw <us...@example.net> writes:

> 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/

Ilya Zakharevich

unread,
Dec 15, 2009, 10:24:26 PM12/15/09
to
On 2009-12-16, monkeys paw <us...@example.net> wrote:
> for my $anum ($lower .. $upper) {
> push @allnums, $anum;
> }

Better use

push @allnums, $lower .. $upper;

Ilya

cha...@pulsenet.com

unread,
Dec 15, 2009, 10:32:14 PM12/15/09
to
On Dec 15, 8:27 pm, monkeys paw <u...@example.net> wrote:
> Following code has quoted numbers in it, but i want
> just integers. What's easiest way?

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
];

monkeys paw

unread,
Dec 16, 2009, 12:46:49 AM12/16/09
to

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.

Uri Guttman

unread,
Dec 16, 2009, 12:52:32 AM12/16/09
to
>>>>> "mp" == monkeys paw <us...@example.net> writes:

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 ---------

monkeys paw

unread,
Dec 16, 2009, 12:54:09 AM12/16/09
to
John Bokma wrote:
> monkeys paw <us...@example.net> writes:
>
>> 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


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

Uri Guttman

unread,
Dec 16, 2009, 1:14:41 AM12/16/09
to
>>>>> "mp" == monkeys paw <us...@example.net> writes:

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.

J�rgen Exner

unread,
Dec 16, 2009, 1:58:36 AM12/16/09
to
monkeys paw <us...@example.net> wrote:

>Ben Morrow wrote:
>The $num variable represents user input. If they enter 5-20 i
>need to push all the integers in between on an array

my ($low, $high) = split /-/, $num;
push @array, $low..$high;

jue

s...@netherlands.com

unread,
Dec 16, 2009, 4:19:21 PM12/16/09
to
On Tue, 15 Dec 2009 20:27:37 -0500, monkeys paw <us...@example.net> wrote:

>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

s...@netherlands.com

unread,
Dec 16, 2009, 4:53:40 PM12/16/09
to

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

s...@netherlands.com

unread,
Dec 16, 2009, 5:19:55 PM12/16/09
to
On Wed, 16 Dec 2009 13:53:40 -0800, s...@netherlands.com wrote:

>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

jl_...@hotmail.com

unread,
Dec 16, 2009, 7:24:48 PM12/16/09
to


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

monkeys paw

unread,
Dec 16, 2009, 11:57:42 PM12/16/09
to
s...@netherlands.com wrote:
> On Wed, 16 Dec 2009 13:53:40 -0800, s...@netherlands.com wrote:
>
>> 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

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.

Uri Guttman

unread,
Dec 17, 2009, 12:12:03 AM12/17/09
to
>>>>> "mp" == monkeys paw <us...@example.net> writes:

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?

monkeys paw

unread,
Dec 17, 2009, 5:26:09 PM12/17/09
to
Uri Guttman wrote:
>>>>>> "mp" == monkeys paw <us...@example.net> writes:
>
> 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
>

0 new messages