다음과 같이 PHP에서지도를 사용하고 있습니다.
function func($v) {
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);
함수에서 값의 인덱스를 얻을 수 있습니까?
또한-인덱스가 필요한 코드를 작성하는 경우 맵 대신 for 루프를 사용해야합니까?
답변:
물론 할 수 있습니다. array_keys():
function func($v, $k)
{
// key is now $k
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map('func', $values, array_keys($values));
var_dump($mapped);
array_map()
, 임의의 수의 인수를 제공 할 수 있습니다. :)
array_keys
가 원래 배열과 동일한 순서로 유지 된다는 것을 보장하지 않으므로 매우 위험한 접근 방식 입니다. 따라서 키를 잘못된 값에 매핑하게 될 수 있습니다. 안전한 방법은 array_keys
의 두 번째 인수 로만 사용한 array_map
다음 use
문을 사용 하여 배열을 클로저로 전달하는 것입니다.
익명 배열을 통해 익명 함수를 매핑 할 때 키에 액세스 할 수있는 방법이 없습니다.
array_map(
function($val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
array_reduce는 키에 대한 액세스 권한도 얻지 못합니다. array_walk는 키에 액세스 할 수 있지만 배열은 참조로 전달되므로 간접 계층이 필요합니다.
일부 솔루션은 다음과 같습니다.
원래 배열을 변경하기 때문에 이것은 나쁘다. 또한 상용구 "array ()"호출은 배열 길이에 따라 선형 적으로 증가합니다.
array_map(
function($pair) use ($foo) {
list($key, $val) = $pair;
/* ... */
},
array(array(key1, val1),
array(key2, val2),
/* ... */));
우리는 원래 배열에서 행동하고 있고 상용구는 일정하지만 기존 변수를 쉽게 제거 할 수 있습니다.
$i_hope_this_does_not_conflict = array(key1 => val1,
key2 => val2,
/* ... */);
array_map(
function($key, $val) use ($foo) { /* ... */ },
array_keys($i_hope_this_does_not_conflict),
$i_hope_this_does_not_conflict);
unset($i_hope_this_does_not_conflict);
함수 범위를 사용하여 기존 이름을 방해하는 것을 방지 할 수 있지만 "사용"이라는 추가 레이어를 추가해야합니다.
call_user_func(
function($arr) use ($foo) {
return array_map(function($key, $val) use ($foo) { /* ... */ },
array_keys($arr),
$arr);
},
array(key1 => val1,
key2 => val2,
/* ... */));
"사용"상용구를 방지하기 위해 원래 범위에서 매핑 할 함수를 정의합니다.
call_user_func(
function($f, $arr) {
return array_map($f, array_keys($arr), $arr);
},
function($key, $val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
주목해야 할 흥미로운 점은 마지막 원샷 함수가 멋지고 일반적인 시그니처를 가지고 있고 array_map과 매우 비슷하다는 것입니다. 이 이름을 지정하고 다시 사용할 수 있습니다.
function array_mapk($f, $arr) {
return array_map($f, array_keys($arr), $arr);
}
애플리케이션 코드는 다음과 같습니다.
array_mapk(
function($key, $val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
위의 내용을 작성할 때 참조로 전달되는 인수가 필요하기 때문에 array_walk를 무시했습니다. 그러나 이후 call_user_func를 사용하여이 문제를 해결하는 것이 쉽다는 것을 깨달았습니다. 지금까지 이것이 최고의 버전이라고 생각합니다.
call_user_func(
'array_walk',
array(key1 => val1,
key2 => val2,
/* ... */),
function($val, $key) use ($foo) { /* ... */ });
매우 간단합니다.
array_map fuction : 인덱스 키가 없습니다!
$params = [4,6,2,11,20];
$data = array_map(function($v) { return ":id{$v}";}, $params);
array (size=5)
0 => string ':id4' (length=4)
1 => string ':id6' (length=4)
2 => string ':id2' (length=4)
3 => string ':id11' (length=5)
4 => string ':id20' (length=5)
이제 array_keys와 결합하십시오.
$data = array_map(
function($k) use ($params) { return ":id{$k}_${params[$k]}"; },
array_keys($params)
);
array (size=5)
0 => string ':id0_4' (length=6)
1 => string ':id1_6' (length=6)
2 => string ':id2_2' (length=6)
3 => string ':id3_11' (length=7)
4 => string ':id4_20' (length=7)
다음을 사용하여 자신 만의지도 기능을 만들 수 있습니다 foreach
.
<?php
function myCallback($key, $val)
{
var_dump("myCallback - key: $key, val: $val");
return $val * 2;
}
function foreachMap($callback, $givenArray) {
$result = [];
foreach ($givenArray as $key=>$val) {
$result[$key] = $callback($key, $val);
}
return $result;
}
$values = array(4, 6, 3);
$mapped = foreachMap('myCallback', $values);
var_dump($mapped);