7

I was trying to build a new array based on an existing array.

#!/usr/bin/perl
#join
use warnings;
use strict;

my @names = ('jacob', 'michael', 'joshua', 'mathew');
my @t_names = join ("\t" , @names);
my @t_names2 = join ("\t", $names[0],$names[2]);
print @t_names, "\n";
print @t_names2, "\n";

The test script allows me to join 2 elements from the old array to form a new array. But what if my array has 1000 elements and I would like to form a new array that contains only a selective portion of the 1000 elements (say, element 3 and 3 multiples). I tried join ("\t", $names[0,2]) but perl doesn't recognize $names[0,2] (output suggests that $names[0,2] is "recognized" as $names[2]. And not sure what this error means "multidimensional syntax not supported at join.pl"

If join is not the right function, what other way could I build a partial array from an existing array? Thank you.

1
  • Just realized this example misrepresents my REAL problem with "join" function. But both answers have helped with another issue that I am struggling with. Thanks a lot !! Commented Apr 19, 2013 at 21:15

2 Answers 2

11

To get a slice of an array, use @names[0,2], not $names[0,2].

To get an explanation of an error message, use diagnostics;, which gives:

Multidimensional syntax $names[0,2] not supported at ...

(W syntax) Multidimensional arrays aren't written like $foo[1,2,3]. They're written like $foo[1][2][3], as in C.

which is perl noticing you are doing something wrong but being wrong about what you were trying to do :)

join creates a string, never a list, so presumably you want to just:

my @new_array = @names[ @indexes_to_select ];

To select only indexes from 3 on that are multiples of 3:

my @new_array = @names[ grep $_ % 3 == 0, 3..$#names ];
Sign up to request clarification or add additional context in comments.

Comments

10

Whenever you want more than one thing out of an array, whether it's all the items or some subset, you use @ instead of $.

You can select any subset of items from an array with @arrayname[list], where list is a list of indexes. You can put a literal list of comma-separated index values, but you can also put any expression that returns a list. ysth's solution uses the expression grep $_ % 3 == 0, 3..$#names. Breaking it down, that uses these elements:

  • $#names to get the index of the last element in @names
  • the range construct .. to generate a list of all the numbers from 3 up to that value
  • grep to extract from that list of numbers only the ones matching a condition
  • that condition being the expression $_ % 3 == 0, which means "the remainder when the number is divided by 3 is 0", which of course is only true for multiples of 3

So if the array has 1000 elements, then $#names is 999, and 3..$#names is a 997-element list containing the numbers (3,4,5,6,7,8,...) all the way up to 999. Running grep $_ % 3 == 0 on that list returns a 333-element list containing the numbers (3,6,9,12,...) all the way up to 999, and then asking for @names[3,6,9,12,...,996,999] returns the 333 elements located at those positions in the @names array.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.