Sida Zhang
Sida Zhang

Reputation: 1

Split an array into two arrays in perl

I am trying to split the array into two different arrays. The first one will be @product, And the second one will be @digit.

@products = qw/Diapers 759230 TrashBags 272616 ToiletPaper 267112 Condoms 987456 Pencils 231948 Pillows 898923 Crayons 123997 Sheets 231223 Paper 235442 Cups 124409 Napkins 029399/;

the result for print @product would be: DiapersTrashBagsToiletPaperCondomsPencilsPillowsCrayonsSheetsPaperCupsNapkins ...

Upvotes: 0

Views: 2391

Answers (5)

Borodin
Borodin

Reputation: 126762

Simplypush each value onto one or the other array according to whether its index is even or odd

use strict;
use warnings 'all';

my @products = qw/
    Diapers     759230
    TrashBags   272616
    ToiletPaper 267112
    Condoms     987456
    Pencils     231948
    Pillows     898923
    Crayons     123997
    Sheets      231223
    Paper       235442
    Cups        124409
    Napkins     029399
/;

my ( @product, @digits );

push @{$_ % 2 ? \@digits : \@product}, $products[$_] for 0 .. $#products;

print "@product\n\n";
print "@digits\n\n";

output

Diapers TrashBags ToiletPaper Condoms Pencils Pillows Crayons Sheets Paper Cups Napkins

759230 272616 267112 987456 231948 898923 123997 231223 235442 124409 029399

Upvotes: 0

ikegami
ikegami

Reputation: 386676

Looks to me like @products contains 2 values for each product. To iterate over the products, you can use natatime from the must-have List::MoreUtils module.

use List::MoreUtils qw( natatime );

my $iter = natatime(2, @products);
while (my @product = $iter->()) {
   ...
}

So, to answer your question, you can use the following:

use List::MoreUtils qw( natatime );

my (@product_names, @product_ids);
my $iter = natatime(2, @products);
while (my @product = $iter->()) {
   push @product_names, $product[0];
   push @product_ids,   $product[1];
}

Upvotes: 2

Matt Jacob
Matt Jacob

Reputation: 6553

Assuming the following for both examples below:

use strict;
use warnings;

my @products = qw/Diapers 759230 TrashBags 272616 ToiletPaper 267112 Condoms 987456 Pencils 231948 Pillows 898923 Crayons 123997 Sheets 231223 Paper 235442 Cups 124409 Napkins 029399/;

If you don't care about the order, exploit the properties of a hash:

my %hash = @products;
my @digits = values(%hash);
my @product = keys(%hash);

The name and the number of a given product will be at same index in both @product and @digits, but the order of the products in @product/@digits will be different than the order in @products.

If you want the order to be the same, slice the even and odd array indices:

my @digits = @products[ grep { ! ($_ % 2) } 0 .. $#products ];
my @product = @products[ grep { $_ % 2 } 0 .. $#products ];

Upvotes: 5

Vida Wang
Vida Wang

Reputation: 416

It seems most reliable to view @products as a list of pairs, so I'd split the values based on the index in @products.

my (@diag, @product);
for my $i (0..$#products){
    if($i & 1 == 1){
        push(@diag,$products[$i]);
    }else {
        push(@product,$products[$i]);
    }
}
print "\@diag:".join(";",@diag)."\n";
print "\@product:".join(";",@product)."\n";

The result is:

@diag:759230;272616;267112;987456;231948;898923;123997;231223;235442;124409;029399
@product:Diapers;TrashBags;ToiletPaper;Condoms;Pencils;Pillows;Crayons;Sheets;Paper;Cups;Napkins

Upvotes: 1

Sagar Motani
Sagar Motani

Reputation: 124

You can either iterate array using for,

foreach (@products){
    if(/\d/){
        push(@digits,$_);
    }else{
        push(@product,$_);
    }
}

Alternatively, you can grep from the array

my(@product) = grep { !/\d/ } @products;
my(@digits) = grep { /\d/ } @products;

Upvotes: 2

Related Questions