Skip to content

Arrays, Hashes, and Lists

Collecting and Organizing Data

Version: 1.0 Year: 2026


Copyright (c) 2025-2026 Ryan Thomas Robson / Robworks Software LLC. Licensed under CC BY-NC-ND 4.0. You may share this material for non-commercial purposes with attribution, but you may not distribute modified versions.


Scalars hold a single value. That gets you surprisingly far, but real programs need collections - ordered lists of items, and named lookups that map keys to values. Perl gives you two aggregate data types for this: arrays and hashes. Everything else - lists, slices, iteration patterns, and nested structures - builds on top of these two.

This guide covers the tools you need to collect, organize, filter, transform, and iterate over data in Perl.


Arrays

An array is an ordered collection of scalars, identified by the @ sigil. Each element has a numeric index starting at 0.

Creating Arrays

# List assignment
my @colors = ('red', 'green', 'blue');

# qw() - quote words, splits on whitespace
my @days = qw(Monday Tuesday Wednesday Thursday Friday);

# Range operator
my @nums = (1..10);       # 1, 2, 3, ... 10
my @letters = ('a'..'z'); # a, b, c, ... z

# Empty array
my @empty = ();

The qw() operator is a shorthand for quoting a list of words. It splits on whitespace and returns a list of strings - no commas or quotes needed.

Accessing Elements

When you access a single element from an array, you use the $ sigil because a single element is a scalar:

my @fruits = ('apple', 'banana', 'cherry', 'date');

print $fruits[0];   # apple  (first element)
print $fruits[2];   # cherry (third element)
print $fruits[-1];  # date   (last element)
print $fruits[-2];  # cherry (second from last)

Negative indices count backwards from the end. -1 is the last element, -2 is second-to-last, and so on.

Array Length and Last Index

Two common operations: getting the number of elements and getting the last valid index.

my @arr = ('a', 'b', 'c', 'd');

# Last index: $#array
print $#arr;           # 3 (indices 0..3)

# Element count: scalar @array
print scalar @arr;     # 4

# These are equivalent ways to access the last element
print $arr[$#arr];     # d
print $arr[-1];        # d

$#array returns the index of the last element (one less than the count). scalar @array forces the array into scalar context, where an array evaluates to its element count. Any situation that expects a single value triggers scalar context automatically - if (@array) is true when the array is non-empty.

Array in Boolean Context

An empty array evaluates to 0 (false) in boolean context, and a non-empty array evaluates to its element count (true). This means if (@array) { ... } is the idiomatic way to check whether an array has elements.


Array Operations

Perl provides built-in functions to add, remove, and rearrange array elements without manual index management.

Adding and Removing Elements

my @stack = (1, 2, 3);

# push/pop: work on the END of the array
push @stack, 4;          # @stack = (1, 2, 3, 4)
push @stack, 5, 6;       # @stack = (1, 2, 3, 4, 5, 6)
my $top = pop @stack;    # $top = 6, @stack = (1, 2, 3, 4, 5)

# shift/unshift: work on the BEGINNING of the array
my $first = shift @stack;    # $first = 1, @stack = (2, 3, 4, 5)
unshift @stack, 0;           # @stack = (0, 2, 3, 4, 5)
unshift @stack, -2, -1;      # @stack = (-2, -1, 0, 2, 3, 4, 5)

push and pop make the array behave like a stack (last-in, first-out). shift and unshift work from the front - useful for queues (first-in, first-out). All four modify the array in place.

Splice: The Swiss Army Knife

splice can insert, remove, or replace elements at any position:

my @arr = ('a', 'b', 'c', 'd', 'e');

# splice(ARRAY, OFFSET, LENGTH, REPLACEMENT_LIST)

# Remove 2 elements starting at index 1
my @removed = splice(@arr, 1, 2);
# @removed = ('b', 'c'), @arr = ('a', 'd', 'e')

# Insert without removing (LENGTH = 0)
splice(@arr, 1, 0, 'x', 'y');
# @arr = ('a', 'x', 'y', 'd', 'e')

# Replace 1 element at index 2
splice(@arr, 2, 1, 'z');
# @arr = ('a', 'x', 'z', 'd', 'e')

Think of splice as the generalized form. push, pop, shift, and unshift are just convenient shortcuts for common splice operations.

Reverse and Sort

my @letters = ('c', 'a', 'd', 'b');

# reverse returns a new list in reversed order
my @backwards = reverse @letters;  # ('b', 'd', 'a', 'c')

# sort returns a new list in sorted order (alphabetical by default)
my @sorted = sort @letters;        # ('a', 'b', 'c', 'd')

# Neither modifies the original
print "@letters\n";  # c a d b

reverse and sort return new lists - the original array stays untouched unless you assign back to it: @letters = sort @letters;

Sort Is Alphabetical by Default

sort compares elements as strings by default. This means sort (10, 2, 30) produces (10, 2, 30) because the string "10" comes before "2" in ASCII order. You need a custom comparator for numeric sorting - covered in the Sorting section below.


Lists and List Assignment

A list is an ordered sequence of scalars. It is not a data type - it is a temporary construct that exists during evaluation. Arrays store lists, but a list and an array are not the same thing.

# This is a list literal
(1, 2, 3)

# Assigned to an array, it becomes the array's contents
my @nums = (1, 2, 3);

# List assignment to scalars
my ($x, $y, $z) = (10, 20, 30);
print "$x $y $z\n";  # 10 20 30

Swapping Variables

List assignment makes variable swapping trivial - no temporary variable needed:

my ($a, $b) = ('first', 'second');
($a, $b) = ($b, $a);
print "$a $b\n";  # second first

Perl evaluates the right side completely before assigning to the left side, so the swap works without a temp.

Array Slices

An array slice extracts multiple elements at once, returning a list. Use the @ sigil because you are getting multiple values:

my @arr = ('zero', 'one', 'two', 'three', 'four');

# Slice: specific indices
my @subset = @arr[1, 3];       # ('one', 'three')

# Slice: range
my @middle = @arr[1..3];       # ('one', 'two', 'three')

# Slice assignment
@arr[0, 4] = ('ZERO', 'FOUR');
print "@arr\n";  # ZERO one two three FOUR

The sigil change is a common source of confusion: $arr[0] (one element, scalar) vs. @arr[0,2] (multiple elements, list). The sigil indicates what you are getting back, not what the variable is.

Context in Assignment

When a list has more values than variables, extras are discarded. When it has fewer, remaining variables get undef:

# Extra values discarded
my ($first, $second) = (10, 20, 30, 40);
# $first = 10, $second = 20 (30 and 40 are lost)

# Missing values become undef
my ($a, $b, $c) = (1, 2);
# $a = 1, $b = 2, $c = undef

# An array in a list absorbs everything remaining
my ($head, @rest) = (1, 2, 3, 4, 5);
# $head = 1, @rest = (2, 3, 4, 5)

Array Absorbs All Remaining Values

If you put an array in the middle of a list assignment, it will consume all remaining values and leave subsequent variables as undef:

my (@arr, $last) = (1, 2, 3, 4);
# @arr = (1, 2, 3, 4), $last = undef  <-- probably not what you wanted

Always put arrays and hashes at the end of a list assignment.


Iteration

foreach / for

The most common way to iterate over an array is foreach:

my @names = qw(Alice Bob Charlie);

foreach my $name (@names) {
    print "Hello, $name!\n";
}

foreach and for are interchangeable when used with a list - Perl treats them identically:

# These are the same
foreach my $item (@list) { ... }
for my $item (@list) { ... }

Most Perl programmers use for (shorter) for list iteration and reserve the C-style syntax when they actually need it.

The Default Variable: $_

If you omit the loop variable, Perl uses $_, the default variable:

my @words = qw(hello world);

for (@words) {
    print "Word: $_\n";
}

Many built-in functions operate on $_ by default: print, chomp, split, lc, uc, and others. This makes $_ the implicit "it" that flows through your code.

C-Style for Loop

When you need an index counter, use the C-style form:

my @items = qw(alpha beta gamma);

for (my $i = 0; $i <= $#items; $i++) {
    print "$i: $items[$i]\n";
}

Output:

0: alpha
1: beta
2: gamma

Modifying Elements During Iteration

The loop variable in for is an alias to the actual array element, not a copy. Modifying it changes the array:

my @nums = (1, 2, 3, 4);

for my $n (@nums) {
    $n *= 10;
}

print "@nums\n";  # 10 20 30 40

Alias Behavior

This alias behavior is intentional and efficient - Perl does not copy the element. But it also means you can accidentally modify your data. If you need a copy, assign to a new variable inside the loop: my $copy = $n;

while with Arrays

You can drain an array with while and shift:

my @queue = qw(first second third);

while (my $item = shift @queue) {
    print "Processing: $item\n";
}
# @queue is now empty

This pattern treats the array as a queue: process the front element, then remove it.


Sorting

Default sort compares elements as strings using Perl's cmp operator. For anything else, you supply a comparison block.

Default Sort (Alphabetical)

my @words = qw(banana cherry apple date);
my @sorted = sort @words;
print "@sorted\n";  # apple banana cherry date

Numeric Sort

The spaceship operator <=> compares two numbers and returns -1, 0, or 1:

my @nums = (42, 5, 17, 100, 3);
my @sorted = sort { $a <=> $b } @nums;
print "@sorted\n";  # 3 5 17 42 100

# Descending: swap $a and $b
my @desc = sort { $b <=> $a } @nums;
print "@desc\n";  # 100 42 17 5 3

Inside the sort block, $a and $b are special package variables that Perl sets to the two elements being compared. The block must return a negative number, zero, or positive number to indicate ordering.

Case-Insensitive Sort

my @names = qw(Charlie alice Bob);
my @sorted = sort { lc($a) cmp lc($b) } @names;
print "@sorted\n";  # alice Bob Charlie

The cmp operator does string comparison (like <=> does numeric comparison). Wrapping in lc() normalizes case before comparing.

Multi-Key Sort

Chain comparisons with || (or) to break ties:

my @people = (
    { name => 'Alice',   age => 30 },
    { name => 'Bob',     age => 25 },
    { name => 'Charlie', age => 30 },
);

my @sorted = sort {
    $a->{age} <=> $b->{age}       # primary: age ascending
    ||
    $a->{name} cmp $b->{name}     # secondary: name ascending
} @people;

for my $p (@sorted) {
    print "$p->{name}: $p->{age}\n";
}
# Bob: 25
# Alice: 30
# Charlie: 30

The || short-circuits: if the first comparison returns non-zero, that result is used. If it returns zero (equal ages), the second comparison breaks the tie.

The Schwartzian Transform

When sorting by a computed value, you do not want to recompute it on every comparison. The Schwartzian transform caches the sort key:

# Sort files by size (compute stat only once per file)
my @sorted =
    map  { $_->[0] }                    # 3. extract filename
    sort { $a->[1] <=> $b->[1] }        # 2. sort by size
    map  { [$_, -s $_] }                # 1. pair filename with size
    @files;

This reads bottom-to-top: wrap each element with its computed key, sort by the key, then unwrap. Named after Randal Schwartz, who popularized the pattern on Usenet.


Hashes

A hash (also called an associative array) is an unordered collection of key-value pairs, identified by the % sigil. Keys are always strings. Values are scalars.

Creating Hashes

# Fat comma (=>) auto-quotes the left side
my %person = (
    name => 'Alice',
    age  => 30,
    city => 'Portland',
);

# Equivalent using plain commas (but less readable)
my %person = ('name', 'Alice', 'age', 30, 'city', 'Portland');

The fat comma => is syntactically identical to a comma, but it auto-quotes the word on its left side. This makes hash initialization readable and eliminates the need for quotes on simple keys.

Hash Structure

A hash maps string keys to scalar values. Unlike arrays, there is no defined order:

flowchart LR
    H["%colors"] --> K1["'red'"] --> V1["'#FF0000'"]
    H --> K2["'green'"] --> V2["'#00FF00'"]
    H --> K3["'blue'"] --> V3["'#0000FF'"]

Accessing Values

Use the $ sigil (you are retrieving a single scalar value) with curly braces:

my %data = (name => 'Alice', age => 30, city => 'Portland');

print $data{name};    # Alice
print $data{age};     # 30

# Assigning a new key-value pair
$data{email} = 'alice@example.com';

# Overwriting an existing value
$data{age} = 31;

Sigil Summary

The sigil tells you what you are getting back, not what the variable is:

Expression Sigil Meaning
%hash % The entire hash
$hash{key} $ One scalar value
@hash{@keys} @ A list of values (hash slice)

Testing and Deleting Keys

my %config = (debug => 1, verbose => 0, timeout => 30);

# exists: does the key exist? (regardless of value)
if (exists $config{debug}) {
    print "debug key exists\n";
}

# defined: is the value defined? (not undef)
if (defined $config{verbose}) {
    print "verbose is defined (value: $config{verbose})\n";  # prints, value is 0
}

# delete: remove a key-value pair
delete $config{timeout};
print exists $config{timeout} ? "yes" : "no";  # no

exists checks whether a key is present. defined checks whether the value is not undef. delete removes the key-value pair entirely. The distinction matters: a key can exist with a value of undef, 0, or an empty string - all of which are valid.

Hash Slices

Like array slices, you can extract multiple values at once:

my %scores = (math => 95, english => 88, science => 92, history => 78);

# Hash slice: returns a list of values
my @subset = @scores{qw(math science)};
print "@subset\n";  # 95 92

# Hash slice assignment
@scores{qw(art music)} = (85, 90);

Note the @ sigil on the slice - you are getting back a list of values, not a single scalar.


Hash Iteration

Hashes have no inherent order, but Perl gives you several ways to walk through all key-value pairs.

keys, values, each

my %inventory = (apples => 12, bananas => 6, cherries => 50);

# keys: returns a list of all keys
my @fruits = keys %inventory;
print "@fruits\n";  # (order not guaranteed)

# values: returns a list of all values
my @counts = values %inventory;
print "@counts\n";  # (order not guaranteed)

# each: returns the next (key, value) pair
while (my ($fruit, $count) = each %inventory) {
    print "$fruit: $count\n";
}

keys and values return complete lists. each returns one pair at a time and maintains an internal iterator - useful for very large hashes where you do not want to build the entire key list in memory.

Avoid each in Most Code

The each function has a hidden internal iterator tied to the hash. If you exit a while (each) loop early, the iterator is not reset, and the next call to each resumes where you left off. This causes subtle bugs. Prefer for my $key (keys %hash) unless you have a specific reason to use each.

Sorted Iteration

Since hash order is unpredictable, sort the keys when you need consistent output:

my %capitals = (
    France  => 'Paris',
    Germany => 'Berlin',
    Japan   => 'Tokyo',
    Brazil  => 'Brasilia',
);

for my $country (sort keys %capitals) {
    printf "%-10s => %s\n", $country, $capitals{$country};
}

Output:

Brazil     => Brasilia
France     => Paris
Germany    => Berlin
Japan      => Tokyo

You can also sort by value:

# Sort by value (alphabetical)
for my $key (sort { $capitals{$a} cmp $capitals{$b} } keys %capitals) {
    print "$key: $capitals{$key}\n";
}

Powerful List Operations

Perl provides several built-in functions for transforming and filtering lists without explicit loops. These are the workhorses of idiomatic Perl code.

grep: Filter a List

grep returns elements where the block evaluates to true:

my @numbers = (1..20);

# Keep only even numbers
my @even = grep { $_ % 2 == 0 } @numbers;
print "@even\n";  # 2 4 6 8 10 12 14 16 18 20

# Keep non-empty strings
my @words = ('hello', '', 'world', '', 'perl');
my @nonempty = grep { length $_ } @words;
print "@nonempty\n";  # hello world perl

# grep with a regex
my @errors = grep { /error/i } @log_lines;

grep is Perl's list filter. The block runs once for each element, with $_ set to the current element. Elements where the block returns true are included in the result.

map: Transform a List

map applies a transformation to every element and returns the results:

my @names = qw(alice bob charlie);

# Capitalize each name
my @upper = map { ucfirst $_ } @names;
print "@upper\n";  # Alice Bob Charlie

# Square each number
my @nums = (1, 2, 3, 4, 5);
my @squares = map { $_ ** 2 } @nums;
print "@squares\n";  # 1 4 9 16 25

# map can return multiple values per element
my @pairs = map { ($_, $_ * 2) } (1, 2, 3);
print "@pairs\n";  # 1 2 2 4 3 6

map is the transformation counterpart to grep. The block runs for each element and returns whatever it produces. If the block returns a list, those values are flattened into the result.

split and join

split breaks a string into a list. join combines a list into a string:

# split: string -> list
my $csv = "Alice,30,Portland";
my @fields = split /,/, $csv;
print "$fields[0]\n";   # Alice
print "$fields[1]\n";   # 30

# join: list -> string
my @parts = ('usr', 'local', 'bin');
my $path = join '/', @parts;
print "$path\n";         # usr/local/bin

# Split on whitespace (default behavior)
my $line = "  hello   world  ";
my @words = split ' ', $line;    # ('hello', 'world')

split with a String vs. Regex

split ' ', $str (with a literal space string, not a regex) has special behavior: it splits on any whitespace and discards leading whitespace. This matches awk's default field splitting. split /\s+/, $str does not discard leading whitespace and may produce an empty first field.

Chaining Operations

Combine map, grep, sort, and join to build data pipelines:

my @raw = qw(banana APPLE cherry apple BANANA Cherry);

# Normalize, deduplicate, sort, and format
my @result =
    sort
    grep { !$seen{$_}++ }
    map  { lc $_ }
    @raw;

print join(', ', @result), "\n";
# apple, banana, cherry

Read from bottom to top: map lowercases everything, grep keeps only the first occurrence of each value (using %seen to track duplicates), sort orders alphabetically.

# Sum of squares of even numbers from 1-20
my $sum = 0;
$sum += $_ for
    map  { $_ ** 2 }
    grep { $_ % 2 == 0 }
    (1..20);

print "$sum\n";  # 1540

Nested Data Structures

So far, arrays hold scalars and hashes map strings to scalars. But what if you need an array of arrays, or a hash whose values are arrays? Perl handles this with references - scalar values that point to other data structures. A full treatment of references comes in a later guide, but you need the basics here to build real-world data structures.

References in Brief

A reference is a scalar that holds the memory address of another variable. Create one with \ and dereference with the appropriate sigil or arrow notation:

my @colors = ('red', 'green', 'blue');
my $ref = \@colors;       # $ref is a reference to @colors

print $ref->[0];           # red (arrow notation)
print ${$ref}[1];          # green (block dereference)

Anonymous references skip the named variable:

my $arr_ref = ['red', 'green', 'blue'];   # anonymous array ref
my $hash_ref = { name => 'Alice', age => 30 };  # anonymous hash ref

Square brackets [] create an anonymous array reference. Curly braces {} (in a value context) create an anonymous hash reference.

Arrays of Arrays

my @matrix = (
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
);

# Access element at row 1, column 2
print $matrix[1][2], "\n";    # 6
print $matrix[1]->[2], "\n";  # 6 (same thing - arrow is optional between brackets)

# Iterate
for my $row (@matrix) {
    print join(', ', @$row), "\n";
}
# 1, 2, 3
# 4, 5, 6
# 7, 8, 9

Each element of @matrix is a reference to an anonymous array. $matrix[1] gives you the reference, and [2] indexes into the array it points to.

Hashes of Arrays

Group related lists under named keys:

my %departments = (
    Engineering => ['Alice', 'Charlie', 'Eve'],
    Marketing   => ['Bob', 'Diana'],
    Support     => ['Frank', 'Grace', 'Hank'],
);

# Access a specific person
print $departments{Engineering}[0], "\n";  # Alice

# Add to a department
push @{$departments{Marketing}}, 'Ivan';

# Iterate
for my $dept (sort keys %departments) {
    my @members = @{$departments{$dept}};
    print "$dept: ", join(', ', @members), "\n";
}
# Engineering: Alice, Charlie, Eve
# Marketing: Bob, Diana, Ivan
# Support: Frank, Grace, Hank

Nested Data Structure

Here is how a hash of arrays looks in memory:

flowchart TD
    R["%departments"] --> E["'Engineering'"]
    R --> M["'Marketing'"]
    E --> EA["['Alice', 'Charlie', 'Eve']"]
    M --> MA["['Bob', 'Diana']"]

Each key points to a reference, and each reference points to an array of scalars.

Hashes of Hashes

The most common nested structure for record-like data:

my %users = (
    alice => {
        email => 'alice@example.com',
        role  => 'admin',
        age   => 30,
    },
    bob => {
        email => 'bob@example.com',
        role  => 'user',
        age   => 25,
    },
);

# Access nested value
print $users{alice}{email}, "\n";   # alice@example.com

# Add a new user
$users{charlie} = {
    email => 'charlie@example.com',
    role  => 'user',
    age   => 28,
};

# Iterate over all users
for my $name (sort keys %users) {
    my $info = $users{$name};
    printf "%-10s %-25s %s\n", $name, $info->{email}, $info->{role};
}

Output:

alice      alice@example.com         admin
bob        bob@example.com           user
charlie    charlie@example.com       user

Arrow Notation

When chaining dereferences, the arrow -> between adjacent brackets is optional:

my %data = (
    servers => [
        { name => 'web1', ip => '10.0.0.1' },
        { name => 'web2', ip => '10.0.0.2' },
    ],
);

# All three are equivalent
print $data{servers}->[0]->{name};  # web1 (explicit arrows)
print $data{servers}[0]{name};      # web1 (arrows optional between brackets)
print ${$data{servers}}[0]{name};   # web1 (block dereference)

The arrow-between-brackets rule applies only between adjacent subscripts. The first arrow after a variable name is still required: $ref->[0] (not $ref[0], which would access @ref).

Autovivification

Perl automatically creates intermediate data structures when you access a nested path that does not exist yet:

my %data;
$data{a}{b}{c} = 'deep';
# Perl silently created $data{a} as a hashref, and $data{a}{b} as a hashref

This is convenient but can mask typos. The autovivification pragma on CPAN lets you disable it selectively.


Putting It All Together

Here is a complete example that combines arrays, hashes, list operations, sorting, and nested structures to solve a practical problem:

use strict;
use warnings;

# Log entries: timestamp, severity, message
my @log = (
    { time => '09:01', level => 'INFO',  msg => 'Server started' },
    { time => '09:05', level => 'WARN',  msg => 'Disk usage at 80%' },
    { time => '09:12', level => 'ERROR', msg => 'Connection refused to db1' },
    { time => '09:15', level => 'INFO',  msg => 'Backup completed' },
    { time => '09:22', level => 'ERROR', msg => 'Connection refused to db2' },
    { time => '09:30', level => 'WARN',  msg => 'Memory usage at 75%' },
    { time => '09:45', level => 'ERROR', msg => 'Timeout on api endpoint' },
);

# Count entries by severity
my %counts;
$counts{$_->{level}}++ for @log;

print "Summary:\n";
for my $level (sort keys %counts) {
    printf "  %-8s %d entries\n", $level, $counts{$level};
}

# Extract error messages
my @errors = map  { "$_->{time} - $_->{msg}" }
             grep { $_->{level} eq 'ERROR' }
             @log;

print "\nErrors:\n";
print "  $_\n" for @errors;

# Group messages by severity
my %by_level;
for my $entry (@log) {
    push @{$by_level{$entry->{level}}}, $entry->{msg};
}

print "\nGrouped:\n";
for my $level (sort keys %by_level) {
    print "  $level:\n";
    print "    - $_\n" for @{$by_level{$level}};
}

Output:

Summary:
  ERROR    3 entries
  INFO     2 entries
  WARN     2 entries

Errors:
  09:12 - Connection refused to db1
  09:22 - Connection refused to db2
  09:45 - Timeout on api endpoint

Grouped:
  ERROR:
    - Connection refused to db1
    - Connection refused to db2
    - Timeout on api endpoint
  INFO:
    - Server started
    - Backup completed
  WARN:
    - Disk usage at 80%
    - Memory usage at 75%

This pattern - filter with grep, transform with map, group into hashes, sort for output - is the core of practical Perl data processing.


Quick Reference

Operation Syntax Description
Create array my @arr = (1, 2, 3) Ordered list of scalars
Access element $arr[0] Single element (scalar context)
Last index $#arr Highest valid index
Count scalar @arr Number of elements
Add to end push @arr, $val Append element(s)
Remove from end pop @arr Remove and return last
Add to front unshift @arr, $val Prepend element(s)
Remove from front shift @arr Remove and return first
Array slice @arr[1,3,5] Multiple elements
Create hash my %h = (k => 'v') Key-value pairs
Access value $h{key} Single value (scalar context)
Key exists? exists $h{key} Boolean test
Delete key delete $h{key} Remove pair
All keys keys %h List of keys
All values values %h List of values
Hash slice @h{qw(a b)} Multiple values
Filter list grep { ... } @list Keep matching elements
Transform list map { ... } @list Apply block to each
Sort list sort { ... } @list Custom ordering
Split string split /,/, $str String to list
Join list join ',', @list List to string

Further Reading

  • perldata - Perl data types: scalars, arrays, and hashes
  • perlfunc - complete list of Perl built-in functions
  • perlref - Perl references and nested data structures
  • perldsc - Perl data structures cookbook (arrays of arrays, hashes of hashes, etc.)
  • perllol - manipulating arrays of arrays
  • perlop - Perl operators including <=>, cmp, =>, and qw()
  • Learning Perl, Chapter 3-6 - the "Llama Book" coverage of lists, arrays, hashes, and I/O
  • Intermediate Perl - the "Alpaca Book," focused on references and data structures

Previous: Scalars, Strings, and Numbers | Next: Control Flow | Back to Index

Comments