// PHP uses the term 'array' to refer to associative arrays - referred to in Perl // as 'hashes' - and for the sake of avoiding confusion, the Perl terminology will // be used. As a matter of interest, PHP does not sport a vector, matrix, or list // type: the 'array' [Perl 'hash'] serves all these roles $age = array('Nat' => 24, 'Jules' => 25, 'Josh' => 17); $age['Nat'] = 24; $age['Jules'] = 25; $age['Josh'] = 17; $age = array_combine(array('Nat', 'Jules', 'Josh'), array(24, 25, 17)); // ------------ $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); $food_colour['Apple'] = 'red'; $food_colour['Banana'] = 'yellow'; $food_colour['Lemon'] = 'yellow'; $food_colour['Carrot'] = 'orange'; $food_colour = array_combine(array('Apple', 'Banana', 'Lemon', 'Carrot'), array('red', 'yellow', 'yellow', 'orange')); |
$hash[$key] = $value; // ------------ $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); $food_colour['Raspberry'] = 'pink'; echo "Known foods:\n"; foreach($food_colour as $food => $colour) echo "{$food}\n"; |
// Returns TRUE on all existing entries with non-NULL values if (isset($hash[$key])) ; // entry exists else ; // no such entry // ------------ // Returns TRUE on all existing entries regardless of attached value if (array_key_exists($key, $hash)) ; // entry exists else ; // no such entry // ---------------------------- $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); foreach(array('Banana', 'Martini') as $name) { if (isset($food_colour[$name])) echo "{$name} is a food.\n"; else echo "{$name} is a drink.\n"; } // ---------------------------- $age = array('Toddler' => 3, 'Unborn' => 0, 'Phantasm' => NULL); foreach(array('Toddler', 'Unborn', 'Phantasm', 'Relic') as $thing) { echo "{$thing}:"; if (array_key_exists($thing, $age)) echo ' exists'; if (isset($age[$thing])) echo ' non-NULL'; if ($age[$thing]) echo ' TRUE'; echo "\n"; } |
// Remove one, or more, hash entries unset($hash[$key]); unset($hash[$key1], $hash[$key2], $hash[$key3]); // Remove entire hash unset($hash); // ---------------------------- function print_foods() { // Perl example uses a global variable global $food_colour; $foods = array_keys($food_colour); echo 'Foods:'; foreach($foods as $food) echo " {$food}"; echo "\nValues:\n"; foreach($foods as $food) { $colour = $food_colour[$food]; if (isset($colour)) echo " {$colour}\n"; else echo " nullified or removed\n"; } } // ------------ $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); echo "Initially:\n"; print_foods(); // Nullify an entry $food_colour['Banana'] = NULL; echo "\nWith 'Banana' nullified\n"; print_foods(); // Remove an entry unset($food_colour['Banana']); echo "\nWith 'Banana' removed\n"; print_foods(); // Destroy the hash unset($food_colour); |
// Access keys and values foreach($hash as $key => $value) { ; // ... } // Access keys only foreach(array_keys($hash) as $key) { ; // ... } // Access values only foreach($hash as $value) { ; // ... } // ---------------------------- $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); foreach($food_colour as $food => $colour) { echo "{$food} is {$colour}\n"; } foreach(array_keys($food_colour) as $food) { echo "{$food} is {$food_colour[$food]}\n"; } // ---------------------------- // 'countfrom' - count number of messages from each sender $line = fgets(STDIN); while (!feof(STDIN)) { if (preg_match('/^From: (.*)/', $line, $matches)) { if (isset($from[$matches[1]])) $from[$matches[1]] += 1; else $from[$matches[1]] = 1; } $line = fgets(STDIN); } if (isset($from)) { echo "Senders:\n"; foreach($from as $sender => $count) echo "{$sender} : {$count}\n"; } else { echo "No valid data entered\n"; } |
// PHP offers, 'print_r', which prints hash contents in 'debug' form; it also // works recursively, printing any contained arrays in similar form // Array // ( // [key1] => value1 // [key2] => value2 // ... // ) print_r($hash); // ------------ // Based on Perl example; non-recursive, so contained arrays not printed correctly foreach($hash as $key => $value) { echo "{$key} => $value\n"; } // ---------------------------- // Sorted by keys // 1. Sort the original hash ksort($hash); // 2. Extract keys, sort, traverse original in key order $keys = array_keys($hash); sort($keys); foreach($keys as $key) { echo "{$key} => {$hash[$key]}\n"; } // Sorted by values // 1. Sort the original hash asort($hash); // 2. Extract values, sort, traverse original in value order [warning: finds // only first matching key in the case where duplicate values exist] $values = array_values($hash); sort($values); foreach($values as $value) { echo $value . ' <= ' . array_search($value, $hash) . "\n"; } |
// Unless sorted, hash elements remain in the order of insertion. If care is taken to // always add a new element to the end of the hash, then element order is the order // of insertion. The following function, 'array_push_associative' [modified from original // found at 'array_push' section of PHP documentation], does just that function array_push_associative(&$arr) { foreach (func_get_args() as $arg) { if (is_array($arg)) foreach ($arg as $key => $value) { $arr[$key] = $value; $ret++; } else $arr[$arg] = ''; } return $ret; } // ------------ $food_colour = array(); // Individual calls, or ... array_push_associative($food_colour, array('Banana' => 'Yellow')); array_push_associative($food_colour, array('Apple' => 'Green')); array_push_associative($food_colour, array('Lemon' => 'Yellow')); // ... one call, one array; physical order retained // array_push_associative($food_colour, array('Banana' => 'Yellow', 'Apple' => 'Green', 'Lemon' => 'Yellow')); print_r($food_colour); echo "\nIn insertion order:\n"; foreach($food_colour as $food => $colour) echo " {$food} => {$colour}\n"; $foods = array_keys($food_colour); echo "\nStill in insertion order:\n"; foreach($foods as $food) echo " {$food} => {$food_colour[$food]}\n"; |
foreach(array_slice(preg_split('/\n/', `who`), 0, -1) as $entry) { list($user, $tty) = preg_split('/\s/', $entry); $ttys[$user][] = $tty; // Could instead do this: // $user = array_slice(preg_split('/\s/', $entry), 0, 2); // $ttys[$user[0]][] = $user[1]; } ksort($ttys); // ------------ foreach($ttys as $user => $all_ttys) { echo "{$user}: " . join(' ', $all_ttys) . "\n"; } // ------------ foreach($ttys as $user => $all_ttys) { echo "{$user}: " . join(' ', $all_ttys) . "\n"; foreach($all_ttys as $tty) { $stat = stat('/dev/$tty'); $pwent = posix_getpwuid($stat['uid']); $user = isset($pwent['name']) ? $pwent['name'] : 'Not available'; echo "{$tty} owned by: {$user}\n"; } } |
// PHP offers the 'array_flip' function to perform the task of exchanging the keys / values // of a hash i.e. invert or 'flip' a hash $reverse = array_flip($hash); // ---------------------------- $surname = array('Babe' => 'Ruth', 'Mickey' => 'Mantle'); $first_name = array_flip($surname); echo "{$first_name['Mantle']}\n"; // ---------------------------- $argc == 2 || die("usage: {$argv[0]} food|colour\n"); $given = $argv[1]; $colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); $food = array_flip($colour); if (isset($colour[$given])) echo "{$given} is a food with colour: {$colour[$given]}\n"; if (isset($food[$given])) echo "{$food[$given]} is a food with colour: {$given}\n"; // ---------------------------- $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); foreach($food_colour as $food => $colour) { $foods_with_colour[$colour][] = $food; } $colour = 'yellow'; echo "foods with colour {$colour} were: " . join(' ', $foods_with_colour[$colour]) . "\n"; |
// PHP implements a swag of sorting functions, most designed to work with numerically-indexed // arrays. For sorting hashes, the 'key' sorting functions are required: // * 'ksort', 'krsort', 'uksort' // Ascending order ksort($hash); // Descending order [i.e. reverse sort] krsort($hash); // Comparator-based sort function comparator($left, $right) { // Compare left key with right key return $left > $right; } uksort($hash, 'comparator'); // ---------------------------- $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); // ------------ ksort($food_colour); foreach($food_colour as $food => $colour) { echo "{$food} is {$colour}\n"; } // ------------ uksort($food_colour, create_function('$left, $right', 'return $left > $right;')); foreach($food_colour as $food => $colour) { echo "{$food} is {$colour}\n"; } |
// PHP offers the 'array_merge' function for this task [a related function, 'array_combine', // may be used to create a hash from an array of keys, and one of values, respectively] // Merge two, or more, arrays $merged = array_merge($a, $b, $c); // Create a hash from array of keys, and of values, respectively $hash = array_combine($keys, $values); // ------------ // Can always merge arrays manually foreach(array($h1, $h2, $h3) as $hash) { foreach($hash as $key => $value) { // If same-key values differ, only latest retained $merged[$key] = $value; // Do this to append values for that key // $merged[$key][] = $value; } } // ---------------------------- $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); $drink_colour = array('Galliano' => 'yellow', 'Mai Tai' => 'blue'); // ------------ $ingested_colour = array_merge($food_colour, $drink_colour); // ------------ $substance_colour = array(); foreach(array($food_colour, $drink_colour) as $hash) { foreach($hash as $substance => $colour) { if (array_key_exists($substance, $substance_colour)) { echo "Warning {$substance_colour[$substance]} seen twice. Using first definition.\n"; continue; } $substance_colour[$substance] = $colour; } } |
// PHP offers a number of array-based 'set operation' functions: // * union: array_merge // * intersection: array_intersect and family // * difference: array_diff and family // which may be used for this type of task // Keys occurring in both hashes $common = array_intersect_key($h1, $h2); // Keys occurring in the first hash [left side], but not in the second hash $this_not_that = array_diff_key($h1, $h2); // ---------------------------- $food_colour = array('Apple' => 'red', 'Banana' => 'yellow', 'Lemon' => 'yellow', 'Carrot' => 'orange'); $citrus_colour = array('Lemon' => 'yellow', 'Orange' => 'orange', 'Lime' => 'green'); $non_citrus = array_diff_key($food_colour, $citrus_colour); |
// PHP implements a special type known as a 'resource' that encompasses things like file handles, // sockets, database connections, and many others. The 'resource' type is, essentially, a // reference variable that is not readily serialisable. That is to say: // * A 'resource' may be converted to a string representation via the 'var_export' function // * That same string cannot be converted back into a 'resource' // So, in terms of array handling, 'resource' types may be stored as array reference values, // but cannot be used as keys. // // I suspect it is this type of problem that the Perl::Tie package helps resolve. However, since // PHP doesn't, AFAIK, sport a similar facility, the examples in this section cannot be // implemented using file handles as keys $filenames = array('/etc/termcap', '/vmlinux', '/bin/cat'); foreach($filenames as $filename) { if (!($fh = fopen($filename, 'r'))) continue; // Cannot do this as required by the Perl code: // $name[$fh] = $filename; // Ok $name[$filename] = $fh; } // Would traverse array via: // // foreach(array_keys($name) as $fh) // ... // or // // foreach($name as $fh => $filename) // ... // but since '$fh' cannot be a key, either of these will work: // // foreach($name as $filename => $fh) // or foreach(array_values($name) as $fh) { fclose($fh); } |
// PHP hashes are dynamic expanding and contracting as entries are added, and removed, // respectively. Thus, there is no need to presize a hash, nor is there, AFAIK, any // means of doing so except by the number of datums used when defining the hash // zero elements $hash = array(); // ------------ // three elements $hash = array('Apple' => 'red', 'Lemon' => 'yellow', 'Carrot' => 'orange'); |
foreach($array as $element) $count[$element] += 1; |
$father = array('Cain' => 'Adam', 'Abel' => 'Adam', 'Seth' => 'Adam', 'Enoch' => 'Cain', 'Irad' => 'Enoch', 'Mehujael' => 'Irad', 'Methusael'=> 'Mehujael', 'Lamech' => 'Methusael', 'Jabal' => 'Lamech', 'Jubal' => 'Lamech', 'Tubalcain' => 'Lamech', 'Enos' => 'Seth'); // ------------ $name = trim(fgets(STDIN)); while (!feof(STDIN)) { while (TRUE) { echo "$name\n"; // Can use either: if (!isset($father[$name])) break; $name = $father[$name]; // or: // if (!key_exists($name, $father)) break; // $name = $father[$name]; // or combine the two lines: // if (!($name = $father[$name])) break; } echo "\n"; $name = trim(fgets(STDIN)); } // ---------------------------- define(SEP, ' '); foreach($father as $child => $parent) { if (!$children[$parent]) $children[$parent] = $child; else $children[$parent] .= SEP . $child; } $name = trim(fgets(STDIN)); while (!feof(STDIN)) { echo $name . ' begat '; if (!$children[$name]) echo "Nothing\n" else echo str_replace(SEP, ', ', $children[$name]) . "\n"; $name = trim(fgets(STDIN)); } // ---------------------------- define(SEP, ' '); $files = array('/tmp/a', '/tmp/b', '/tmp/c'); foreach($files as $file) { if (!is_file($file)) { echo "Skipping {$file}\n"; continue; } if (!($fh = fopen($file, 'r'))) { echo "Skipping {$file}\n"; continue; } $line = fgets($fh); while (!feof($fh)) { if (preg_match('/^\s*#\s*include\s*<([^>]+)>/', $line, $matches)) { if (isset($includes[$matches[1]])) $includes[$matches[1]] .= SEP . $file; else $includes[$matches[1]] = $file; } $line = fgets($fh); } fclose($fh); } print_r($includes); |
// @@INCOMPLETE@@
// @@INCOMPLETE@@
|