Arrays
## Learning Objectives
- Master array manipulation
- Use list operations
- Work with map and grep
- Sort arrays effectively
- Understand array context
## Array Basics
### Creating Arrays
```perl
use strict;
use warnings;
my @empty;
my @nums = (1, 2, 3, 4, 5);
my @mixed = ("hello", 42, 3.14);
my @range = (1 .. 10);
my @letters = ('a' .. 'z');
```
### Array Size
```perl
my @colors = ("red", "green", "blue");
print scalar @colors; # 3 (number of elements)
print $#colors; # 2 (last index)
```
### Accessing Elements
```perl
my @fruits = ("apple", "banana", "cherry");
print $fruits[0]; # "apple"
print $fruits[-1]; # "cherry" (last element)
print $fruits[-2]; # "banana" (second to last)
# Modify
$fruits[0] = "apricot";
```
## List Operations
### Push and Pop
```perl
my @stack = (1, 2, 3);
push @stack, 4; # (1, 2, 3, 4)
my $popped = pop @stack; # Returns 4, @stack = (1, 2, 3)
unshift @stack, 0; # (0, 1, 2, 3)
my $shifted = shift @stack; # Returns 0, @stack = (1, 2, 3)
```
### splice
```perl
my @nums = (1, 2, 3, 4, 5);
# Remove and replace
splice @nums, 1, 2, (10, 20); # (1, 10, 20, 4, 5)
# Just remove
splice @nums, 0, 2; # Returns (1, 10), @nums = (20, 4, 5)
# Just insert
splice @nums, 1, 0, (30, 40); # Insert at position 1
```
### join and split
```perl
my @words = ("Hello", "World", "Perl");
my $sentence = join " ", @words;
print $sentence; # "Hello World Perl"
my $line = "apple,banana,cherry";
my @fruits = split ",", $line;
print "@fruits"; # apple banana cherry
# Split with limit
my @parts = split ":", "a:b:c:d", 2; # ("a", "b:c:d")
```
### reverse
```perl
my @nums = (1, 2, 3, 4, 5);
my @reversed = reverse @nums; # (5, 4, 3, 2, 1)
my @chars = split "", "hello";
my @rev_chars = reverse @chars;
my $rev_string = join "", @rev_chars; # "olleh"
```
## map
### Basic map
```perl
use strict;
use warnings;
my @nums = (1, 2, 3, 4, 5);
# Square each number
my @squares = map { $_ * $_ } @nums;
print "@squares\n"; # 1 4 9 16 25
# Transform strings
my @names = ("alice", "bob", "charlie");
my @caps = map { ucfirst lc $_ } @names;
print "@caps\n"; # Alice Bob Charlie
```
### map with Multiple Expressions
```perl
my %hash = (
a => 1,
b => 2,
c => 3,
);
# Double values
my %doubled = map { $_, $hash{$_} * 2 } keys %hash;
print "$_ => $doubled{$_}\n" for keys %doubled;
```
### map vs foreach
```perl
# map returns transformed list
my @squares = map { $_ * $_ } (1 .. 5);
# foreach just iterates
foreach my $num (1 .. 5) {
print "$num ";
}
```
## grep
### Basic grep
```perl
use strict;
use warnings;
my @nums = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
# Find even numbers
my @evens = grep { $_ % 2 == 0 } @nums;
print "@evens\n"; # 2 4 6 8 10
# Find numbers greater than 5
my @big = grep { $_ > 5 } @nums;
print "@big\n"; # 6 7 8 9 10
```
### grep with Regex
```perl
my @words = ("apple", "banana", "apricot", "cherry", "avocado");
# Words starting with 'a'
my @a_words = grep { /^a/ } @words;
print "@a_words\n"; # apple apricot avocado
# Words containing 'an'
my @an_words = grep { /an/ } @words;
print "@an_words\n"; # banana apricot
```
### grep vs grep not
```perl
my @nums = (1, 2, 3, 4, 5);
my @small = grep { $_ < 4 } @nums; # 1, 2, 3
my @not_small = grep { $_ >= 4 } @nums; # 4, 5
```
## sort
### Basic sort
```perl
use strict;
use warnings;
my @nums = (3, 1, 4, 1, 5, 9, 2, 6);
my @sorted = sort @nums;
print "@sorted\n"; # 1 1 2 3 4 5 6 9 (string sort!)
# String sort
my @words = ("banana", "apple", "cherry");
my @alpha = sort @words;
print "@alpha\n"; # apple banana cherry
```
### Numeric Sort
```perl
my @nums = (3, 1, 4, 1, 5, 9, 2, 6);
my @sorted = sort { $a <=> $b } @nums;
print "@sorted\n"; # 1 1 2 3 4 5 6 9
# Reverse numeric
my @rev = sort { $b <=> $a } @nums;
print "@rev\n"; # 9 6 5 4 3 2 1 1
```
### Custom Sort
```perl
# By length
my @words = ("apple", "hi", "banana", "a", "cherry");
my @by_len = sort { length($a) <=> length($b) } @words;
print "@by_len\n"; # a hi apple banana cherry
# Case-insensitive sort
my @mixed = ("Apple", "banana", "Cherry");
my @sorted = sort { lc($a) cmp lc($b) } @mixed;
print "@sorted\n"; # Apple banana Cherry
# Stable sort (preserve order of equals)
```
### Sort Hash Keys/Values
```perl
my %scores = (
Alice => 95,
Bob => 87,
Charlie => 92,
);
# Sort by values
my @by_score = sort { $scores{$a} <=> $scores{$b} } keys %scores;
print "@by_score\n"; # Bob Charlie Alice
```
## Advanced Array Operations
### List Assignment
```perl
my ($first, $second, @rest) = (1, 2, 3, 4, 5);
print "$first, $second, @rest\n"; # 1, 2, 3 4 5
# Swap values
my ($x, $y) = (10, 20);
($x, $y) = ($y, $x); # Swap!
```
### List as Return Value
```perl
sub get_range {
return (1 .. 10);
}
my @nums = get_range(); # (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
```
### Flattening
```perl
my @a = (1, 2);
my @b = (3, 4);
my @combined = (@a, @b); # (1, 2, 3, 4)
# Nested arrays flatten
my @nested = (1, [2, 3], 4); # Actually (1, 2, 3, 4) in list context
```
### List Context
```perl
# Force list context
my @copy = (1, 2, 3);
# In scalar context, last value
my $last = (1, 2, 3); # $last = 3
# Force scalar with scalar()
my $count = scalar @array;
```
## Reducing Arrays
### Manual Reduction
```perl
sub sum {
my $total = 0;
foreach my $val (@_) {
$total += $val;
}
return $total;
}
print sum(1, 2, 3, 4, 5); # 15
```
### Using reduce (List::Util)
```perl
use List::Util qw(reduce);
my $sum = reduce { $a + $b } 1, 2, 3, 4, 5;
my $product = reduce { $a * $b } 1 .. 5;
```
## Summary
- Arrays created with `@` sigil and parentheses
- `$#array` gives last index, `scalar @array` gives length
- Push/pop work on end, shift/unshift on beginning
- `splice` for advanced insertion/removal
- `map` transforms each element
- `grep` filters elements by condition
- `sort` orders elements (use `<=>` for numeric)
- `reverse` reverses list order
- `join` combines, `split` breaks apart
- Lists flatten in list context
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →