Here is a simple way to highlight the matched words in the search results:
<?php
function highlight($word) {
static $num = 1;
return '<span class="word' . $num++ . '">' . $word . '</span>';
}
$text = "ala bala nica turska panica";
$search = "bala turska";
$words = explode(' ', $search);
echo str_replace($words, array_map("highlight", $words), $text);
array_map
(PHP 4 >= 4.0.6, PHP 5)
array_map — 指定した配列の要素にコールバック関数を適用する
説明
array_map() は、arr1 の各要素に callback 関数を適用した後、 その全ての要素を含む配列を返します。 callback 関数が受け付けるパラメータの数は、 array_map() に渡される配列の数に一致している必要があります。
パラメータ
- callback
-
配列の各要素に適用するコールバック関数。
- arr1
-
コールバック関数を適用する配列。
- array
-
コールバック関数に渡す引数を指定する配列の可変リスト。
返り値
arr1 の各要素に callback 関数を適用した後、 その全ての要素を含む配列を返します。
例
例1 array_map() の例
<?php
function cube($n)
{
return($n * $n * $n);
}
$a = array(1, 2, 3, 4, 5);
$b = array_map("cube", $a);
print_r($b);
?>
この例では、$b の内容は以下のようになります。
Array ( [0] => 1 [1] => 8 [2] => 27 [3] => 64 [4] => 125 )
例
例2 array_map() - もっと配列を使ってみる例
<?php
function show_Spanish($n, $m)
{
return("The number $n is called $m in Spanish");
}
function map_Spanish($n, $m)
{
return(array($n => $m));
}
$a = array(1, 2, 3, 4, 5);
$b = array("uno", "dos", "tres", "cuatro", "cinco");
$c = array_map("show_Spanish", $a, $b);
print_r($c);
$d = array_map("map_Spanish", $a , $b);
print_r($d);
?>
上の例の出力は以下となります。
// printout of $c Array ( [0] => The number 1 is called uno in Spanish [1] => The number 2 is called dos in Spanish [2] => The number 3 is called tres in Spanish [3] => The number 4 is called cuatro in Spanish [4] => The number 5 is called cinco in Spanish ) // printout of $d Array ( [0] => Array ( [1] => uno ) [1] => Array ( [2] => dos ) [2] => Array ( [3] => tres ) [3] => Array ( [4] => cuatro ) [4] => Array ( [5] => cinco ) )
通常、二つ以上の配列を使用する場合、 それらの長さは等しい必要があります。 これは、 コールバック関数が対応する要素に対して並行して適用されるためです。 配列の長さが等しくない場合、最も短い配列は空の要素で拡張されます。
この関数の面白い使用方法として、 配列の配列を構築するというものがあります。 これは、コールバック関数の名前として NULL を使用することにより、簡単に実行できるものです。
例3 配列の配列を生成する
<?php
$a = array(1, 2, 3, 4, 5);
$b = array("one", "two", "three", "four", "five");
$c = array("uno", "dos", "tres", "cuatro", "cinco");
$d = array_map(null, $a, $b, $c);
print_r($d);
?>
上の例の出力は以下となります。
Array ( [0] => Array ( [0] => 1 [1] => one [2] => uno ) [1] => Array ( [0] => 2 [1] => two [2] => dos ) [2] => Array ( [0] => 3 [1] => three [2] => tres ) [3] => Array ( [0] => 4 [1] => four [2] => cuatro ) [4] => Array ( [0] => 5 [1] => five [2] => cinco ) )
配列引数に文字列のキーが含まれる場合は、 渡した配列がひとつだけなら返される配列に文字列キーが含まれることになります。 複数の引数を渡した場合は、返される配列は常に整数キーとなります。
例4 array_map() - 文字列キーの例
<?php
$arr = array("stringkey" => "value");
function cb1($a) {
return array ($a);
}
function cb2($a, $b) {
return array ($a, $b);
}
var_dump(array_map("cb1", $arr));
var_dump(array_map("cb2", $arr, $arr));
var_dump(array_map(null, $arr));
var_dump(array_map(null, $arr, $arr));
?>
上の例の出力は以下となります。
array(1) { ["stringkey"]=> array(1) { [0]=> string(5) "value" } } array(1) { [0]=> array(2) { [0]=> string(5) "value" [1]=> string(5) "value" } } array(1) { ["stringkey"]=> string(5) "value" } array(1) { [0]=> array(2) { [0]=> string(5) "value" [1]=> string(5) "value" } }
array_map
27-Apr-2008 10:32
03-Apr-2008 06:21
Wish this was built in. Mimics Ruby and Prototype's array pluck function. Returns specific key/column from an array of objects.
<?php
function array_pluck($key, $array)
{
if (is_array($key) || !is_array($array)) return array();
$funct = create_function('$e', 'return is_array($e) && array_key_exists("'.$key.'",$e) ? $e["'. $key .'"] : null;');
return array_map($funct, $array);
}
// usage:
$a = array(array("id"=>10, "name"=>"joe"), array("id"=>11, "name"=>"bob"));
$ids = array_pluck("id", $a); // == array(10,11)
$names = array_pluck("name", $a); // == array("joe", "bob")
//works on non-keyed arrays also:
$a = array(array(3,4), array(5,6));
$col2 = array_pluck(1,$a); // == array(4,6) (grab 2nd column of data)
?>
13-Mar-2008 08:48
I was miffed that array_map didn't have a way to pass values *and* keys to the callback, but then I realized I could do this:
function callback($k, $v) { ... }
array_map( "callback", array_keys($array), $array);
18-Feb-2008 07:10
Could also use things like...
array_keys(); and array_values(); offcourse...
However it's just an example off recursion via this function..
Which I found pretty handy at times dealing with arrays..
could also use:
<?php
call_user_func(array($this, __FUNCTION), $args);
?>
or
<?php
call_user_fuc_array(array($this, __FUNCTION__), $array);
?>
or
<?php
class{
public function __construct($arg){
if(is_array($arg)){
new self($arg);
}
else{
echo $arg.'<br/>'.PHP_EOL;
}
}
}
?>
Anyway.. plenty off examples..
It was just an idea for others...
08-Feb-2008 10:39
loaded67 at hotmail dot com, there is a little error in the add func params values.
Warning: Missing argument 2 for test::add(), called in /tmp/test.php on line 34 and defined in /tmp/test.php on line 6
Array => <br/>
now it runs...
<?php
class test{
//private $container = array();
final public function add($key, $value=NULL){
/* params values fix */
$value = $value==NULL?$key:$value;
/* recursion */
if(is_array($value)){
array_map(array($this, __FUNCTION__), array_keys($value), array_values($value));
}
/* procedural */
else{
echo $key.' => '.$value.'<br/>'.PHP_EOL;
// do stuff...
// if(!isset($this->container[$key])){
// $this->container[$key] = $value;
// }
//else{ // trigger_error() xor throw new Exception?
// echo 'allready exists!<br/>'.PHP_EOL;
//}
}
}
}
//
$array = array (
'one' => 'value1',
'two' => 'value2',
'three' => 'value3'
);
$t = new test;
$t->add($array);
?>
good luck!
08-Feb-2008 07:59
this function is really nice for recursion in php!!!
example in a class:
<?php
class test{
//private $container = array();
final public function add($key, $value){
/* recursion */
if(is_array($value)){
array_map(array($this, __FUNCTION__), array_keys($value), array_values($value));
}
/* procedural */
else{
echo $key.' => '.$value.'<br/>'.PHP_EOL;
// do stuff...
// if(!isset($this->container[$key])){
// $this->container[$key] = $value;
// }
//else{ // trigger_error() xor throw new Exception?
// echo 'allready exists!<br/>'.PHP_EOL;
//}
}
}
}
//
$array = array (
'one' => 'value1',
'two' => 'value2',
'three' => 'value3'
);
$t = new test;
$t->add($array);
?>
you could easiely do this without a class too offcourse!
used in php 5.2.5
23-Jan-2008 12:02
This function behaves exactly like array_map but additionally does not reject non-array arguments. Instead, it transforms them with the array_fill function to a constant valued array of required length according to the other array arguments (if any) and executes the original array_map function.
<?php
function array_map2() {
$args = func_get_args();
$callback = array_shift($args);
$args = array_map(
create_function('$a,$max','return is_array($a)? $a: array_fill(0,$max,$a);'),
$args,array_fill(0,count($args),array_reduce($args,
create_function('$v,$w','return max($v,is_array($w)? count($w): 1);'))));
array_unshift($args,$callback);
return call_user_func_array("array_map",$args);
}
?>
Example:
<?php
$get = "first=value1&second=value2&third=value3";
print_r(array_map2("explode","=",explode("&",$get)));
?>
would print out:
<?php
Array
(
[0] => Array
(
[0] => first
[1] => value1
)
[1] => Array
(
[0] => second
[1] => value2
)
[2] => Array
(
[0] => third
[1] => value3
)
)
?>
/pmf
02-Nov-2007 01:02
Adding method support to function by Andref (multidimensionalArrayMap).
function array_map_r( $func, $arr )
{
$newArr = array();
foreach( $arr as $key => $value )
{
$newArr[ $key ] = ( is_array( $value ) ? array_map_r( $func, $value ) : ( is_array($func) ? call_user_func_array($func, $value) : $func( $value ) ) );
}
return $newArr;
}
array_map_r('function', array());
or
array_map_r(array('class', 'method'), array());
19-Jul-2007 11:46
Maybe this one will be useful for someone:
function array_map_helper($mapper, $array) {
$mapper = preg_replace('/^return (.*?);$/', '$1', trim($mapper));
$result = array();
if (preg_match('/(\(?)(.*?)\s*=>\s*(.*?)(\)?)$/', $mapper, $matches)) {
list($full_found, $array_open, $left, $right, $array_close) = $matches;
if ($array_open && $array_close) {
$mapper = '$result[] = array' . $full_found . ';';
} else {
$mapper = '$result[' . $left . '] = ' . $right . ';';
}
} else {
$mapper = '$result[] = ' . $mapper . ';';
}
foreach ($array as $key => $value) {
eval($mapper);
}
return $result;
}
should be used like:
$array = array(array('foo' => 11, 'bar' => 22),
array('foo' => 111, 'bar' => 222),
array('foo' => 1111, 'bar' => 2222));
$mapped = array_map_helper('$value["foo"] => $value["bar"]', $array);
var_dump will give
array(3) {
[11]=>
int(22)
[111]=>
int(222)
[1111]=>
int(2222)
}
or
$mapped = array_map_helper('$value["foo"]', $array);
var_dump will give
array(3) {
[0]=>
int(11)
[1]=>
int(111)
[2]=>
int(1111)
}
or
$mapped = array_map_helper('$value["foo"] + $value["bar"] . " at position $key"', $array);
var_dump will give
array(3) {
[0]=>
string(16) "33 at position 0"
[1]=>
string(17) "333 at position 1"
[2]=>
string(18) "3333 at position 2"
}
25-Oct-2006 04:14
A recursive way to handle multidimensional arrays:
<?php
function multidimensionalArrayMap( $func, $arr )
{
$newArr = array();
foreach( $arr as $key => $value )
{
$newArr[ $key ] = ( is_array( $value ) ? multidimensionalArrayMap( $func, $value ) : $func( $value ) );
}
return $newArr;
}
?>
18-Mar-2006 01:50
Hi benjaminhill,
You can apply a method of a instantiated class to array_maps as follows:
class Maths {
function addOne($input) {
return ($input + 1);
}
}
$maths = new Maths();
$sum = array_map(array($maths, \\\'addOne\\\'), array(1, 2));
// where $maths is the object which has been instantiated before and addOne is its method without its own parameters
var_dump($sum);
The code fragment will return:
array
0 => 2
1 => 3
However, I love a syntax like this:
$sum = array_map($maths->addOne($this), array(1, 2));
where $this should be interpreted as each values extracted from the subsequent array, which in this case is array(1, 2).
This syntax reminds me of Javascript syntax.
PHP\\\'s callback mechanism should be improved.
Here's a function, very helpfull to me, that allows you to map your callback on mixed args.
<?php
function array_smart_map($callback) {
// Initialization
$args = func_get_args() ;
array_shift($args) ; // suppressing the callback
$result = array() ;
// Validating parameters
foreach($args as $key => $arg)
if(is_array($arg)) {
// the first array found gives the size of mapping and the keys that will be used for the resulting array
if(!isset($size)) {
$keys = array_keys($arg) ;
$size = count($arg) ;
// the others arrays must have the same dimension
} elseif(count($arg) != $size) {
return FALSE ;
}
// all keys are suppressed
$args[$key] = array_values($arg) ;
}
// doing the callback thing
if(!isset($size))
// if no arrays were found, returns the result of the callback in an array
$result[] = call_user_func_array($callback, $args) ;
else
for($i=0; $i<$size; $i++) {
$column = array() ;
foreach($args as $arg)
$column[] = ( is_array($arg) ? $arg[$i] : $arg ) ;
$result[$keys[$i]] = call_user_func_array($callback, $column) ;
}
return $result ;
}
?>
Trying with :
<?php
// $_GET is ?foo=bar1-bar2-bar3&bar=foo1
print_r(array_smart_map('explode', '-', $_GET)) ;
?>
Returns :
array(
[foo] => array(
0 => bar1
1 => bar2
2 => bar3
)
[bar] => array(
1 => foo1
)
)
07-Jul-2005 08:53
You can pass values to array_map by reference, essentially allowing you to use it as you would array_walk with multiple arrays as parameters.
A trivial example:
<?php
$a = array(1,2,3,4,5);
$add_func = create_function('&$x, $y', '$x+=$y;');
array_map($add_func, $a, $a);
print_r($a);
?>
Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 8
[4] => 10
)
23-Mar-2005 10:31
The following function does exaclty the same thing of array_map. However, maintains the same index of the input arrays
<?php
function array_map_keys($param1,$param2,$param3=NULL)
{
$res = array();
if ($param3 !== NULL)
{
foreach(array(2,3) as $p_name)
{
if (!is_array(${'param'.$p_name}))
{
trigger_error(__FUNCTION__.'(): Argument #'.$p_name.' should be an array',E_USER_WARNING);
return;
}
}
foreach($param2 as $key => $val)
{
$res[$key] = call_user_func($param1,$param2[$key],$param3[$key]);
}
}
else
{
if (!is_array($param2))
{
trigger_error(__FUNCTION__.'(): Argument #2 should be an array',E_USER_WARNING);
return;
}
foreach($param2 as $key => $val)
{
$res[$key] = call_user_func($param1,$param2[$key]);
}
}
return $res;
}
?>
For instance:
<?php
$arr1 = array(
'3' => 'a',
'4' => 'b',
'5' => 'c'
);
$arr2 = array(
'3' => 'd',
'4' => 'e',
'5' => 'f'
);
$arr3 = array_map_keys(create_function('$a,$b','return $a.$b;'),$arr1,$arr2);
print_r($arr3);
?>
The result will be:
Array
(
[3] => ad
[4] => be
[5] => cf
)
20-Feb-2005 04:29
If you need to call a static method from array_map, this will NOT work:
<?PHP
array_map('myclass::myMethod' , $value);
?>
Instead, you need to do this:
<?PHP
array_map( array('myclass','myMethod') , $value);
?>
It is helpful to remember that this will work with any PHP function which expects a callback argument.
02-Jul-2004 08:42
array_map works also fine with create_function:
<?php
$a = array(1, 2, 3, 4, 5);
$b = array_map(create_function('$n', 'return $n*$n*$n;'), $a);
print_r($b);
?>
if you want to manipulate the elements of the array, instead to on a copy,
than take a look at array_walk:
<?php
$a = array(1, 2, 3, 4, 5);
array_walk($a, create_function('&$n', '$n = $n*$n*$n;'));
print_r($a);
?>
The Result of both is:
Array
(
[0] => 1
[1] => 8
[2] => 27
[3] => 64
[4] => 125
)
10-Apr-2004 09:07
Occasionally, you may find that you need to pull out a column (or several) from an array. Here's a map-like function to do that:
<?php
function &array_shear(&$arrays, $idx1 /* ... */) {
$indexes = func_get_args();
array_shift($indexes);
$newArrays = array ();
foreach (array_keys($arrays) as $arrayKey) {
$newArray = array ();
foreach ($indexes as $index) {
$newArray[$index] = $arrays[$arrayKey][$index];
unset($arrays[$arrayKey][$index]);
}
$newArrays[$arrayKey] = $newArray;
}
return $newArrays;
}
?>
So, doing this:
<?php
$t1 = array (
2 => array ('a', 'b', 'c'),
1 => array ('d', 'e', 'f'),
5 => array ('g', 'h', 'i'),
);
$t2 = array_shear($t1, 1, 0);
?>
will result in:
<?php
$t1 = array (
2 => array ( 2 => 'c', ),
1 => array ( 2 => 'f', ),
5 => array ( 2 => 'i', ),
);
$t2 = array (
2 => array ( 1 => 'b', 0 => 'a', ),
1 => array ( 1 => 'e', 0 => 'd', ),
5 => array ( 1 => 'h', 0 => 'g', ),
);
?>
07-Jan-2003 03:02
A note when doing something allong the lines of:
<?php
class foo {
var $var;
function bar() {
array_map(array($this, "baz"), array(1,2,3));
}
function baz($arg) {
$this->var = $this->var + $arg;
}
}
?>
This will *not* work as expected. You need to pass $this by reference as with:
array_map(array(&$this, "baz"), array(1,2,3));
or you'll be making a copy of the object each time, changing a value, then throwing the result away.
15-Jun-2002 02:07
Here is a better, more true version of a deep array_map. The only negative of this function is that the array is passed by reference, so just be aware of that. (patches welcome)
<?php
function array_map_deep(&$in_array, $in_func, $in_args = array(), $in_index = 1) {
// fix people from messing up the index of the value
if ($in_index < 1) {
$in_index = 1;
}
foreach (array_keys($in_array) as $key) {
// we need a reference, not a copy, normal foreach won't do
$value =& $in_array[$key];
// we need to copy args because we are doing
// manipulation on it farther down
$args = $in_args;
if (is_array($value)) {
array_map_deep($value, $in_func, $in_args, $in_index);
}
else {
array_splice($args, $in_index - 1, $in_index - 1, $value);
$value = call_user_func_array($in_func, $args);
}
}
return $in_array;
}
?>
This is a neat function because you can pass an array, a function, and an array of parameters, and finally, and index of where in the array of parameters for the callback function the contents you are mapping should get replaced. This index is human based (starts at 1), and can be used in something like a preg_replace callback, where the contents must be the 3rd index. Enjoy!