다음은 매우 간단한 PHP 5.5 호환 솔루션입니다.
function array_map_assoc(callable $f, array $a) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
}
제공하는 콜 러블 자체는 두 값을 가진 배열을 반환해야합니다 return [key, value]
. 따라서 내부 호출 array_map
은 배열 배열을 생성합니다. 그런 다음에 의해 단일 차원 배열로 다시 변환됩니다 array_column
.
용법
$ordinals = [
'first' => '1st',
'second' => '2nd',
'third' => '3rd',
];
$func = function ($k, $v) {
return ['new ' . $k, 'new ' . $v];
};
var_dump(array_map_assoc($func, $ordinals));
산출
array(3) {
["new first"]=>
string(7) "new 1st"
["new second"]=>
string(7) "new 2nd"
["new third"]=>
string(7) "new 3rd"
}
부분 적용
다른 배열이지만 동일한 매핑 함수와 함께 함수를 여러 번 사용해야하는 경우 부분 함수 응용 프로그램 ( ' currying ' 관련 )을 호출하여 호출 할 때만 데이터 배열을 전달할 수 있습니다.
function array_map_assoc_partial(callable $f) {
return function (array $a) use ($f) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
};
}
...
$my_mapping = array_map_assoc_partial($func);
var_dump($my_mapping($ordinals));
주어진 것과 동일한 출력을 생성 하며 이전 $func
과 $ordinals
같습니다.
참고 : 매핑 된 함수가 서로 다른 두 입력에 대해 동일한 키 를 반환 하면 이후 키 와 관련된 값 이 이깁니다. array_map_assoc
이전 키가 이길 수 있도록 입력 배열과 출력 결과 를 반대로 바꿉니다. (이 예제에서 반환 된 키는 소스 배열의 키를 통합하므로 충돌 할 수 없으며 차례로 고유해야합니다.)
대안
다음은 위의 변형으로 일부에게는 더 논리적이지만 PHP 5.6이 필요합니다.
function array_map_assoc(callable $f, array $a) {
return array_merge(...array_map($f, array_keys($a), $a));
}
이 변형에서 제공된 함수 (데이터 배열이 매핑되는 함수)는 대신 하나의 행이있는 연관 배열을 반환해야합니다 return [key => value]
. 그런 다음 호출 가능 항목을 매핑 한 결과는 간단히 압축을 풀고로 전달됩니다 array_merge
. 앞서와 같이, 중복 키를 반환하면 나중에 값을 얻습니다.
nb Alex83690은 주석 array_replace
대신 여기 를 사용 하면 array_merge
정수 키가 유지 된다는 의견에 주목했습니다 . array_replace
입력 배열을 수정하지 않으므로 기능 코드에 안전합니다.
PHP 5.3 ~ 5.5 인 경우 다음과 같습니다. array_reduce
이진 +
배열 연산자를 사용 하여 키를 유지하면서 결과 2 차원 배열을 1 차원 배열로 변환합니다.
function array_map_assoc(callable $f, array $a) {
return array_reduce(array_map($f, array_keys($a), $a), function (array $acc, array $a) {
return $acc + $a;
}, []);
}
용법
따라서이 두 가지 변형이 모두 사용됩니다.
$ordinals = [
'first' => '1st',
'second' => '2nd',
'third' => '3rd',
];
$func = function ($k, $v) {
return ['new ' . $k => 'new ' . $v];
};
var_dump(array_map_assoc($func, $ordinals));
메모 =>
대신 ,
에서 $func
.
출력은 이전과 동일하며 각각 이전과 같은 방식으로 부분적으로 적용 할 수 있습니다.
요약
원래 질문의 목표는 호출되는 더 복잡한 기능을 희생하면서 가능한 한 간단하게 호출을 호출하는 것입니다. 특히 키와 값을 나누지 않고 데이터 배열을 단일 인수로 전달할 수 있습니다. 이 답변의 시작 부분에 제공된 기능 사용 :
$test_array = ["first_key" => "first_value",
"second_key" => "second_value"];
$array_map_assoc = function (callable $f, array $a) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
};
$f = function ($key, $value) {
return [$key, $key . ' loves ' . $value];
};
var_dump(array_values($array_map_assoc($f, $test_array)));
또는이 질문에 대해서만 array_map_assoc()
출력 키를 삭제 하는 기능을 단순화 할 수 있습니다 . 질문은 요청하지 않기 때문입니다.
$test_array = ["first_key" => "first_value",
"second_key" => "second_value"];
$array_map_assoc = function (callable $f, array $a) {
return array_map($f, array_keys($a), $a);
};
$f = function ($key, $value) {
return $key . ' loves ' . $value;
};
var_dump($array_map_assoc($f, $test_array));
따라서 대답은 NO 이므로 호출을 피할 수 없지만 고차 함수로 호출되는 array_keys
곳을 추상화 할 수 있습니다 array_keys
.